#include #include #include #include #include #include #include #include #include #include #include #include "fonttest.h" #include "enum.h" #include "glyph.h" #include "rings.h" #include "stringw.h" #include "waterfal.h" #include "whirl.h" #include "ansiset.h" #include "widths.h" #include "gcp.h" #include "eudc.h" #include "dialogs.h" #ifdef USERGETWVTPERF #include #include #include #endif // new flag that for NT 5.0/IE 5.0 is used for testing purpose only #define CF_MM_DESIGNVECTOR 0x02000000L #define SZMAINCLASS "FontTest" #define SZRINGSCLASS "Rings Class" #define SZSTRINGCLASS "String Class" #define SZWATERFALLCLASS "Waterfall Class" #define SZWHIRLCLASS "Whirl Class" #define SZWIDTHSCLASS "Widths Class" #define SZANSISET "AnsiSet" #define SZGLYPHSET "GlyphSet" #define SZDEBUGCLASS "FontTest Debug" #define ALTERNATE_FILL 1 #define WINDING_FILL 2 BOOL bStrokePath=FALSE; BOOL bFillPath=FALSE; int fillMode = WINDING_FILL; int gTime; void CALLBACK Mytimer(HWND hwnd, // handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idEvent, // timer identifier DWORD dwTime ) { gTime++; } INT_PTR CALLBACK SetWorldTransformDlgProc( HWND hdlg , UINT msg , WPARAM wParam , LPARAM lParam ); //---------- Escape Structures ----------- typedef struct _EXTTEXTMETRIC { short etmSize; short etmPointSize; short etmOrientation; short etmMasterHeight; short etmMinScale; short etmMaxScale; short etmMasterUnits; short etmCapHeight; short etmXHeight; short etmLowerCaseAscent; short etmLowerCaseDescent; short etmSlant; short etmSuperscript; short etmSubscript; short etmSuperscriptSize; short etmSubscriptSize; short etmUnderlineOffset; short etmUnderlineWidth; short etmDoubleUpperUnderlineOffset; short etmDoubleLowerUnderlineOffset; short etmDoubleUpperUnderlineWidth; short etmDoubleLowerUnderlineWidth; short etmStrikeoutOffset; short etmStrikeoutWidth; short etmKernPairs; short etmKernTracks; } EXTTEXTMETRIC, FAR *LPEXTTEXTMETRIC; typedef struct _KERNPAIR { WORD wBoth; short sAmount; } KERNPAIR, FAR *LPKERNPAIR; #ifdef USERGETCHARWIDTH typedef struct _CHWIDTHINFO { LONG lMaxNegA; LONG lMaxNegC; LONG lMinWidthD; } CHWIDTHINFO, *PCHWIDTHINFO; BOOL GetCharWidthInfo(HDC hdc, PCHWIDTHINFO pChWidthInfo); #endif //------------------------------------------ HFONT hFontDebug = NULL; HWND hwndMode; UINT wMappingMode = IDM_MMTEXT; UINT wUseGlyphIndex = 0; UINT wCharCoding = IDM_CHARCODING_MBCS; BOOL isCharCodingUnicode = FALSE; LPINT lpintdx = NULL; int SizewszStringGlyph = 0; int sizePdx = 0; BOOL bClipEllipse; BOOL bClipPolygon; BOOL bClipRectangle; PRINTDLG pdlg; // Print Setup Structure LRESULT CALLBACK MainWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); int (WINAPI *lpfnStartDoc )(HDC, DOCINFO FAR*); int (WINAPI *lpfnStartPage)(HDC); int (WINAPI *lpfnEndPage )(HDC); int (WINAPI *lpfnEndDoc )(HDC); int (WINAPI *lpfnAbortDoc )(HDC); XFORM xf = { (FLOAT) 1.0, (FLOAT) 0.0, (FLOAT) 0.0, (FLOAT) 1.0, (FLOAT) 0.0, (FLOAT) 0.0 }; //***************************************************************************** //************************** W I N M A I N ****************************** //***************************************************************************** HANDLE hInstance = 0; HANDLE hPrevInstance = 0; LPSTR lpszCmdLine = 0; int nCmdShow = 0; int __cdecl main( int argc, char *argv[] ) { MSG msg; WNDCLASS wc; RECT rcl; //-------------------------- Register Main Class ---------------------------- hInstance = GetModuleHandle(NULL); lpszCmdLine = argv[0]; nCmdShow = SW_SHOWNORMAL; hInst = hInstance; if( !hPrevInstance ) { memset( &wc, 0, sizeof(wc) ); wc.hCursor = LoadCursor( NULL, IDC_SIZEWE ); wc.hIcon = LoadIcon( hInst, MAKEINTRESOURCE( IDI_FONTTESTICON ) ); wc.lpszMenuName = MAKEINTRESOURCE( IDM_FONTTESTMENU ); wc.lpszClassName = SZMAINCLASS; wc.hbrBackground = GetStockObject( BLACK_BRUSH ); wc.hInstance = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.lpfnWndProc = MainWndProc; if( !RegisterClass( &wc ) ) return 1; } //------------------------- Register Glyph Class ---------------------------- if( !hPrevInstance ) { memset( &wc, 0, sizeof(wc) ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hIcon = NULL; wc.lpszClassName = SZGLYPHCLASS; wc.hbrBackground = GetStockObject( DKGRAY_BRUSH ); wc.hInstance = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.lpfnWndProc = GlyphWndProc; if( !RegisterClass( &wc ) ) return 1; } //------------------------- Register Rings Class ---------------------------- if( !hPrevInstance ) { memset( &wc, 0, sizeof(wc) ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hIcon = NULL; wc.lpszClassName = SZRINGSCLASS; wc.hbrBackground = GetStockObject( WHITE_BRUSH ); wc.hInstance = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.lpfnWndProc = RingsWndProc; if( !RegisterClass( &wc ) ) return 1; } //------------------------ Register String Class ---------------------------- if( !hPrevInstance ) { memset( &wc, 0, sizeof(wc) ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hIcon = NULL; wc.lpszClassName = SZSTRINGCLASS; wc.hbrBackground = GetStockObject( WHITE_BRUSH ); wc.hInstance = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.lpfnWndProc = StringWndProc; if( !RegisterClass( &wc ) ) return 1; } //----------------------- Register Waterfall Class -------------------------- if( !hPrevInstance ) { memset( &wc, 0, sizeof(wc) ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hIcon = NULL; wc.lpszClassName = SZWATERFALLCLASS; wc.hbrBackground = GetStockObject( WHITE_BRUSH ); wc.hInstance = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.lpfnWndProc = WaterfallWndProc; if( !RegisterClass( &wc ) ) return 1; } //------------------------- Register Whirl Class ---------------------------- if( !hPrevInstance ) { memset( &wc, 0, sizeof(wc) ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hIcon = NULL; wc.lpszClassName = SZWHIRLCLASS; wc.hbrBackground = GetStockObject( WHITE_BRUSH ); wc.hInstance = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.lpfnWndProc = WhirlWndProc; if( !RegisterClass( &wc ) ) return 1; } //------------------------- Register AnsiSet Class ---------------------------- if( !hPrevInstance ) { memset( &wc, 0, sizeof(wc) ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hIcon = NULL; wc.lpszClassName = SZANSISET; wc.hbrBackground = GetStockObject( WHITE_BRUSH ); wc.hInstance = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.lpfnWndProc = AnsiSetWndProc; if( !RegisterClass( &wc ) ) return 1; } //------------------------- Register GlyphSet Class ---------------------------- if( !hPrevInstance ) { memset( &wc, 0, sizeof(wc) ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hIcon = NULL; wc.lpszClassName = SZGLYPHSET; wc.hbrBackground = GetStockObject( WHITE_BRUSH ); wc.hInstance = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.lpfnWndProc = GlyphSetWndProc; if( !RegisterClass( &wc ) ) return 1; } //------------------------ Register Widths Class ---------------------------- if( !hPrevInstance ) { memset( &wc, 0, sizeof(wc) ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hIcon = NULL; wc.lpszClassName = SZWIDTHSCLASS; wc.hbrBackground = GetStockObject( WHITE_BRUSH ); wc.hInstance = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.lpfnWndProc = WidthsWndProc; if( !RegisterClass( &wc ) ) return 1; } //------------------------ Create Main Window ------------------------------- hwndMain = CreateWindow( SZMAINCLASS, SZMAINCLASS, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ), NULL, NULL, hInstance, NULL ); ShowWindow( hwndMain, nCmdShow ); UpdateWindow( hwndMain ); GetClientRect( hwndMain, &rcl ); cxScreen = rcl.right; // GetSystemMetrics( SM_CXSCREEN ); cyScreen = rcl.bottom; // GetSystemMetrics( SM_CYSCREEN ); cxBorder = GetSystemMetrics( SM_CXFRAME ); //-------- Create Debug Window in Right Third of Screen ----------- hwndDebug = CreateWindow( "LISTBOX", "FontTest Debug Window", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL | LBS_NOINTEGRALHEIGHT, 2 * cxScreen / 3 + cxBorder -1 , 0, cxScreen / 3, cyScreen, hwndMain, NULL, hInst, NULL ); { HDC hdc; int lfHeight; hdc = CreateIC( "DISPLAY", NULL, NULL, NULL ); lfHeight = -(10 * GetDeviceCaps( hdc, LOGPIXELSY )) / 72; DeleteDC( hdc ); hFontDebug = CreateFont( lfHeight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Courier" ); SendMessage( hwndDebug, WM_SETFONT, (WPARAM) hFontDebug, FALSE ); } // SendMessage( hwndDebug, // WM_SETFONT, // GetStockObject( SYSTEM_FIXED_FONT ), // FALSE ); ShowWindow( hwndDebug, SW_SHOWNORMAL ); UpdateWindow( hwndDebug ); //-------- Create Glyph Window in Left 2/3 of Screen ----------- hwndGlyph = CreateWindow( SZGLYPHCLASS, "FontTest Glyph Window", WS_CHILD, 0, 0, 2 * cxScreen / 3 - 3, cyScreen, hwndMain, NULL, hInst, NULL ); ShowWindow( hwndGlyph, SW_HIDE ); UpdateWindow( hwndGlyph ); //-------- Create Rings Window in Left Half of Screen ----------- hwndRings = CreateWindow( SZRINGSCLASS, "FontTest Rings Window", WS_CHILD, 0, 0, 2 * cxScreen / 3 - 3, cyScreen, hwndMain, NULL, hInst, NULL ); ShowWindow( hwndRings, SW_HIDE ); UpdateWindow( hwndRings ); //-------- Create String Window in Left Half of Screen ---------- hwndString = CreateWindow( SZSTRINGCLASS, "FontTest String Window", WS_CHILD | WS_VISIBLE, 0, 0, 2 * cxScreen / 3 - 3, cyScreen, hwndMain, NULL, hInst, NULL ); ShowWindow( hwndString, SW_HIDE ); UpdateWindow( hwndString ); hwndMode = hwndString; //------ Create Waterfall Window in Left Half of Screen --------- hwndWaterfall = CreateWindow( SZWATERFALLCLASS, "FontTest Waterfall Window", WS_CHILD, 0, 0, 2 * cxScreen / 3 - 3, cyScreen, hwndMain, NULL, hInst, NULL ); ShowWindow( hwndWaterfall, SW_HIDE ); UpdateWindow( hwndWaterfall ); //-------- Create Whirl Window in Left Half of Screen ----------- hwndWhirl = CreateWindow( SZWHIRLCLASS, "FontTest Whirl Window", WS_CHILD, 0, 0, 2 * cxScreen / 3 - 3, cyScreen, hwndMain, NULL, hInst, NULL ); ShowWindow( hwndWhirl, SW_HIDE ); UpdateWindow( hwndWhirl ); //-------- Create AnsiSet Window in Left Half of Screen ----------- hwndAnsiSet = CreateWindow( SZANSISET, "FontTest AnsiSet Window", WS_CHILD, 0, 0, 2 * cxScreen / 3 - 3, cyScreen, hwndMain, NULL, hInst, NULL ); ShowWindow( hwndAnsiSet, SW_HIDE ); UpdateWindow( hwndAnsiSet ); //-------- Create GlyphSet Window in Left Half of Screen ----------- hwndGlyphSet = CreateWindow( SZGLYPHSET, "FontTest GlyphSet Window", WS_CHILD, 0, 0, 2 * cxScreen / 3 - 3, cyScreen, hwndMain, NULL, hInst, NULL ); ShowWindow( hwndGlyphSet, SW_HIDE ); UpdateWindow( hwndGlyphSet ); //-------- Create Widths Window in Left Half of Screen ----------- hwndWidths = CreateWindow( SZWIDTHSCLASS, "FontTest Widths Window", WS_CHILD, 0, 0, 2 * cxScreen / 3 - 3, cyScreen, hwndMain, NULL, hInst, NULL ); ShowWindow( hwndWidths, SW_HIDE ); UpdateWindow( hwndWidths ); //----------------------- Process Messages ------------------------- while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } if( hFontDebug ) DeleteObject( hFontDebug ); return (DWORD)msg.wParam; } //***************************************************************************** //********************* S H O W D I A L O G B O X ********************* //***************************************************************************** INT_PTR ShowDialogBox(DLGPROC DialogProc, int iResource, LPVOID lpVoid ) { INT_PTR rc; DLGPROC lpProc; lpProc = MakeProcInstance( DialogProc, hInst ); if( lpProc == NULL ) return -1; if (!isCharCodingUnicode) { rc = DialogBoxParamA( hInst, (LPCSTR) MAKEINTRESOURCE( iResource ), hwndMain, lpProc, (LPARAM) lpVoid ); } else { rc = DialogBoxParamW( hInst, (LPCWSTR) MAKEINTRESOURCE( iResource ), hwndMain, lpProc, (LPARAM) lpVoid ); } FreeProcInstance( lpProc ); return rc; } //***************************************************************************** //**************************** D P R I N T F ****************************** //***************************************************************************** int Debugging = 1; int iCount = 0; BOOL bLogging = FALSE; char szLogFile[256]; int dprintf (char *fmt, ... ) { int ret; va_list marker; static char szBuffer[256]; if( !Debugging ) return 0; va_start( marker, fmt ); ret = vsprintf( szBuffer, fmt, marker ); //------------------------ Log to Debug List Box ---------------------------- if( hwndDebug != NULL ) { SendMessage( hwndDebug, LB_ADDSTRING, 0, (LPARAM) (LPSTR) szBuffer ); SendMessage( hwndDebug, LB_SETCURSEL, (WPARAM) iCount, 0 ); } //----------------------------- Log to File --------------------------------- if( bLogging ) { int fh; fh = _lopen( szLogFile, OF_WRITE | OF_SHARE_COMPAT ); if( fh == -1 ) fh = _lcreat( szLogFile, 0 ); else _llseek( fh, 0L, 2 ); if( fh != -1 ) { lstrcat( szBuffer, "\r\n" ); _lwrite( fh, szBuffer, lstrlen(szBuffer) ); _lclose( fh ); } } iCount++; return ret; } int dwprintf( wchar_t *fmt, ... ) { int ret; va_list marker; static WCHAR szBuffer[256]; static char szBufferA[256]; if( !Debugging ) return 0; va_start( marker, fmt ); ret = vswprintf( szBuffer, fmt, marker ); //MessageBoxW(NULL, szBuffer, NULL, MB_OK); //------------------------ Log to Debug List Box ---------------------------- if( hwndDebug != NULL ) { SendMessageW( hwndDebug, LB_ADDSTRING, 0, (LPARAM) (LPWSTR) szBuffer ); SendMessage( hwndDebug, LB_SETCURSEL, (WPARAM) iCount, 0 ); } //----------------------------- Log to File --------------------------------- if( bLogging ) { int fh; fh = _lopen( szLogFile, OF_WRITE | OF_SHARE_COMPAT ); if( fh == -1 ) fh = _lcreat( szLogFile, 0 ); else _llseek( fh, 0L, 2 ); if( fh != -1 ) { lstrcatW( szBuffer, L"\r\n" ); SyncStringWtoA(szBufferA, szBuffer, 256); _lwrite( fh, szBufferA, lstrlen(szBufferA) ); _lclose( fh ); } } iCount++; return ret; } // calling dUpdateNow with FALSE prevents the debug listbox from updating // on every string insertion. calling dUpdateNow with TRUE turns on updating // on string insertion and refreshes the display to show the current contents. // Note: change TRUE to FALSE in InvalidateRect when listbox repaint bug is // fixed. void dUpdateNow( BOOL bUpdateNow ) { /* make sure we want to do something first! */ if( !Debugging || !hwndDebug ) return; /* set listbox updating accordingly */ SendMessage( hwndDebug, WM_SETREDRAW, bUpdateNow, 0L ); /* if we are reenabling immediate updating force redraw of listbox */ if( bUpdateNow ) { InvalidateRect(hwndDebug, NULL, FALSE); UpdateWindow(hwndDebug); } } //***************************************************************************** //*********************** C L E A R D E B U G *************************** //***************************************************************************** void ClearDebug( void ) { iCount = 0; SendMessage( hwndDebug, LB_RESETCONTENT, 0, 0 ); } //***************************************************************************** //****************** C R E A T E P R I N T E R D C ******************** //***************************************************************************** HDC CreatePrinterDC( void ) { LPDEVNAMES lpDevNames; LPBYTE lpDevMode; LPSTR lpszDriver, lpszDevice, lpszOutput; if( hdcCachedPrinter ) return hdcCachedPrinter; lpDevNames = (LPDEVNAMES)GlobalLock( pdlg.hDevNames ); lpDevMode = (LPBYTE) GlobalLock( pdlg.hDevMode ); if (!lpDevNames || !lpDevMode) return NULL; lpszDriver = (LPSTR)lpDevNames+lpDevNames->wDriverOffset; lpszDevice = (LPSTR)lpDevNames+lpDevNames->wDeviceOffset; lpszOutput = (LPSTR)lpDevNames+lpDevNames->wOutputOffset; dprintf( "lpszDriver = '%Fs'", lpszDriver ); dprintf( "lpszDevice = '%Fs'", lpszDevice ); dprintf( "lpszOutput = '%Fs'", lpszOutput ); hdcCachedPrinter = CreateDC( lpszDriver, lpszDevice, lpszOutput, (CONST DEVMODE*) lpDevMode ); dprintf( " hdc = 0x%.4X", hdcCachedPrinter ); GlobalUnlock( pdlg.hDevNames ); GlobalUnlock( pdlg.hDevMode ); return hdcCachedPrinter; } //***************************************************************************** //******************** S E T D C M A P M O D E ********************** //***************************************************************************** void SetDCMapMode( HDC hdc, UINT wMode ) { char *psz; switch( wMode ) { case IDM_MMHIENGLISH: SetMapMode( hdc, MM_HIENGLISH ); psz = "MM_HIENGLISH"; break; case IDM_MMLOENGLISH: SetMapMode( hdc, MM_LOENGLISH ); psz = "MM_LOENGLISH"; break; case IDM_MMHIMETRIC: SetMapMode( hdc, MM_HIMETRIC ); psz = "MM_HIMETRIC"; break; case IDM_MMLOMETRIC: SetMapMode( hdc, MM_LOMETRIC ); psz = "MM_LOMETRIC"; break; case IDM_MMTEXT: SetMapMode( hdc, MM_TEXT ); psz = "MM_TEXT"; break; case IDM_MMTWIPS: SetMapMode( hdc, MM_TWIPS ); psz = "MM_TWIPS"; break; case IDM_MMANISOTROPIC: SetMapMode( hdc, MM_ANISOTROPIC ); SetWindowOrgEx( hdc, xWO, yWO , 0); SetWindowExtEx( hdc, xWE, yWE , 0); SetViewportOrgEx( hdc, xVO, yVO , 0); SetViewportExtEx( hdc, xVE, yVE , 0); psz = "MM_ANISOTROPIC"; break; } if (bAdvanced) { SetGraphicsMode(hdc,GM_ADVANCED); SetWorldTransform(hdc,&xf); } else { // reset to unity before resetting compatible ModifyWorldTransform(hdc,NULL, MWT_IDENTITY); SetGraphicsMode(hdc,GM_COMPATIBLE); } // dprintf( "Set DC Map Mode to %s", psz ); } //***************************************************************************** //******************** C R E A T E T E S T I C ************************ //***************************************************************************** HDC CreateTestIC( void ) { HDC hdc; POINT pt[2]; if( wUsePrinterDC ) hdc = CreatePrinterDC(); else hdc = CreateDC( "DISPLAY", NULL, NULL, NULL ); if( !hdc ) { dprintf( "Error creating TestDC" ); return NULL; } SetDCMapMode( hdc, wMappingMode ); cxDevice = GetDeviceCaps( hdc, HORZRES ); cyDevice = GetDeviceCaps( hdc, VERTRES ); pt[0].x = cxDevice; pt[0].y = cyDevice; pt[1].x = 0; pt[1].y = 0; DPtoLP(hdc,&pt[0],2); cxDC = pt[0].x - pt[1].x; cyDC = pt[0].y - pt[1].y; return hdc; } //***************************************************************************** //******************** D E L E T E T E S T I C ************************ //***************************************************************************** void DeleteTestIC( HDC hdc ) { if( hdc != hdcCachedPrinter ) DeleteDC( hdc ); } //***************************************************************************** //********************** D R A W D C A X I S ************************** //***************************************************************************** HRGN hrgnClipping; void DrawDCAxis( HWND hwnd, HDC hdc, BOOL bAxis ) { POINT ptl[2]; RECT rect; int dx10, dy10, dx100, dy100; int xClip1, yClip1, xClip2, yClip2; HRGN hrgn; // dprintf( "Drawing DC Axis" ); //-------------------------- Figure out DC Size ----------------------------- if( hwnd ) { GetClientRect( hwnd, &rect ); ptl[0].x = rect.right; ptl[0].y = rect.bottom; } else { ptl[0].x = GetDeviceCaps( hdc, HORZRES ); ptl[0].y = GetDeviceCaps( hdc, VERTRES ); } cxDevice = ptl[0].x; cyDevice = ptl[0].y; // dprintf( " cxDevice = %d", cxDevice ); // dprintf( " cyDevice = %d", cyDevice ); ptl[1].x = 0; ptl[1].y = 0; DPtoLP(hdc,&ptl[0],2); if ( (wMappingMode != IDM_MMTEXT) && (wMappingMode != IDM_MMANISOTROPIC) && !bAdvanced ) { if( ptl[0].y < 0 ) ptl[0].y = -ptl[0].y; SetViewportOrgEx( hdc, 0, cyDevice , 0); // Adjust Viewport Origin to Lower Left } cxDC = ptl[0].x - ptl[1].x; cyDC = ptl[0].y - ptl[1].y; xDC = ptl[1].x; yDC = ptl[1].y; // dprintf( " cxDC = %d", cxDC ); // dprintf( " cyDC = %d", cyDC ); //---------------------- Draw background ------------------------------------- //TODO: find out from Bodin how we should restrict drawing the background if(!bAxis || isGradientBackground) { TRIVERTEX verticies[2]; GRADIENT_RECT rects[1]; verticies[0].Blue = GetBValue(dwRGBLeftBackgroundColor) << 8; verticies[0].Red = GetRValue(dwRGBLeftBackgroundColor) << 8; verticies[0].Green = GetGValue(dwRGBLeftBackgroundColor) << 8; verticies[0].x = xDC; verticies[0].y = yDC; verticies[1].Blue = GetBValue(dwRGBRightBackgroundColor) << 8; verticies[1].Red = GetRValue(dwRGBRightBackgroundColor) << 8; verticies[1].Green = GetGValue(dwRGBRightBackgroundColor) << 8; verticies[1].x = xDC + cxDC; verticies[1].y = yDC + cyDC; rects[0].UpperLeft = 0; rects[0].LowerRight = 1; #ifdef GI_API GradientFill(hdc, verticies, 2, rects, 1, GRADIENT_FILL_RECT_H); #endif } if(!isGradientBackground) { HBRUSH solidBrush = CreateSolidBrush(dwRGBSolidBackgroundColor); RECT rect; rect.top = yDC; rect.left = xDC; rect.bottom = yDC + cyDC; rect.right = xDC + cxDC; if(solidBrush != NULL) { FillRect(hdc, &rect, solidBrush); DeleteObject(solidBrush); } } //---------------------- Draw Reference Triangle (ugly) --------------------- if (bAxis) { if (!bAdvanced) { dx10 = ptl[0].x / 10; dy10 = ptl[0].y / 10; dx100 = dx10 / 10; dy100 = dy10 / 10; MoveToEx( hdc, dx100, dy100 ,0); LineTo( hdc, dx100+dx10, dy100 ); LineTo( hdc, dx100, dy100+dy10 ); LineTo( hdc, dx100, dy100 ); } else { MoveToEx(hdc,0,0,0); LineTo(hdc,xDC + cxDC/2,yDC + cyDC/2); } } //------------------------- Create Clipping Region -------------------------- xClip1 = cxDevice/2 - cxDevice/4; yClip1 = cyDevice/2 - cyDevice/4; xClip2 = cxDevice/2 + cxDevice/4; yClip2 = cyDevice/2 + cyDevice/4; // dprintf( "Clip1: %d,%d", xClip1, yClip1 ); // dprintf( "Clip2: %d,%d", xClip2, yClip2 ); hrgnClipping = NULL; if( bClipEllipse ) { hrgnClipping = CreateEllipticRgn( xClip1, yClip1, xClip2, yClip2 ); } if( bClipPolygon ) { POINT aptl[5]; aptl[0].x = xClip1; aptl[0].y = cyDevice/2; aptl[1].x = cxDevice/2; aptl[1].y = yClip1; aptl[2].x = xClip2; aptl[2].y = cyDevice/2; aptl[3].x = cxDevice/2; aptl[3].y = yClip2; aptl[4].x = xClip1; aptl[4].y = cyDevice/2; hrgn = CreatePolygonRgn( (LPPOINT)aptl, 5, ALTERNATE ); if( hrgnClipping ) { CombineRgn( hrgnClipping, hrgnClipping, hrgn, RGN_XOR ); DeleteObject( hrgn ); } else hrgnClipping = hrgn; } if( bClipRectangle ) { hrgn = CreateRectRgn( xClip1, yClip1, xClip2, yClip2 ); if( hrgnClipping ) { CombineRgn( hrgnClipping, hrgnClipping, hrgn, RGN_XOR ); DeleteObject( hrgn ); } else hrgnClipping = hrgn; } if( hrgnClipping ) { int rc; RECT r; r.top = yDC; r.left = xDC; r.right = xDC + cxDC; r.bottom = yDC + cyDC; FillRect( hdc, &r, GetStockObject( LTGRAY_BRUSH ) ); // dprintf( "Filling region white" ); rc = FillRgn( hdc, hrgnClipping, GetStockObject( WHITE_BRUSH ) ); // dprintf( " rc = %d", rc ); // dprintf( "Selecting clipping region into DC" ); rc = SelectClipRgn( hdc, hrgnClipping ); // dprintf( " rc = %d", rc ); } } //***************************************************************************** //*********************** C L E A N U P D C *************************** //***************************************************************************** void CleanUpDC( HDC hdc ) { if( hrgnClipping ) { DeleteObject( hrgnClipping ); hrgnClipping = NULL; } } //***************************************************************************** //*********************** H A N D L E C H A R *************************** //***************************************************************************** void HandleChar( HWND hwnd, WPARAM wParam ) { int l; int i; char szBuffer[5*MAX_TEXT]; if( wParam == '\b' ) { if (!isCharCodingUnicode) szStringA[max(0,lstrlenA(szStringA)-1)] = '\0'; else szStringW[max(0,lstrlenW(szStringW)-1)] = L'\0'; } else { if (!isCharCodingUnicode) l = lstrlenA(szStringA); else l = lstrlenW(szStringW); if( l < MAX_TEXT-1 ) { if (!isCharCodingUnicode) { szStringA[l] = (char) wParam; szStringA[l+1] = '\0'; } else { szStringW[l] = (WCHAR) wParam; szStringW[l+1] = L'\0'; } } } szBuffer[0] = 0; for (i=0; (UINT)i 0) { dprintf( " etmKernPairs = %d", etm.etmKernPairs ); dprintf( " " ); if (etm.etmKernPairs) { wSize = etm.etmKernPairs * sizeof(KERNPAIR); if (lpkp = (LPKERNPAIR)malloc(wSize)) { dprintf( "Calling ExtEscape for GETPAIRKERNTABLE" ); wrc = ExtEscape( hdc, GETPAIRKERNTABLE, 0, NULL, wSize, (BYTE *)lpkp ); dprintf( " wrc = %d", wrc ); if (wrc > 0) { dprintf( " First Second Amount"); dprintf( " ======= ======== ========"); for (j = 0; j < etm.etmKernPairs; j++) { dprintf( " %c=%x %c=%x %d", lpkp[j].wBoth & 0x00FF, lpkp[j].wBoth & 0x00FF, lpkp[j].wBoth >> 8, lpkp[j].wBoth >> 8, lpkp[j].sAmount); } } free( lpkp ); } } } dUpdateNow( TRUE ); //Exit: SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); } //***************************************************************************** //*********** S H O W O U T L I N E T E X T M E T R I C S *********** //***************************************************************************** void ShowOutlineTextMetrics( HWND hwnd ) { HDC hdc; HFONT hFont, hFontOld; WORD wrc; LPOUTLINETEXTMETRICA lpotm = NULL; LPOUTLINETEXTMETRICW lpotmW = NULL; hdc = CreateTestIC(); if (!isCharCodingUnicode) hFont = CreateFontIndirectWrapperA( &elfdvA ); else hFont = CreateFontIndirectWrapperW( &elfdvW ); hFontOld = SelectObject( hdc, hFont ); SetTextAlign( hdc, wTextAlign ); dprintf( "Getting size of Outline Text Metrics" ); if (!isCharCodingUnicode) wrc = (WORD)lpfnGetOutlineTextMetricsA( hdc, 0, NULL ); else wrc = (WORD)lpfnGetOutlineTextMetricsW( hdc, 0, NULL ); dprintf( " wrc = %u", wrc ); if( wrc == 0 ) goto Exit; if (!isCharCodingUnicode) { lpotm = (LPOUTLINETEXTMETRIC) calloc( 1, wrc ); dprintf( " lpotm = %Fp", lpotm ); } else { lpotmW = (LPOUTLINETEXTMETRICW) calloc( 1, wrc ); dprintf( " lpotmW = %Fp", lpotmW ); } if( ((!isCharCodingUnicode) && (lpotm == NULL)) || (( isCharCodingUnicode) && (lpotmW == NULL)) ) { dprintf( " Couldn't allocate OutlineTextMetrics structure" ); goto Exit; } if (!isCharCodingUnicode) { lpotm->otmSize = wrc; wrc = (WORD)lpfnGetOutlineTextMetricsA( hdc, wrc, lpotm ); } else { lpotmW->otmSize = wrc; wrc = (WORD)lpfnGetOutlineTextMetricsW( hdc, wrc, lpotmW ); } dprintf( " wrc = %u", wrc ); if( !wrc ) { dprintf( " Error getting outline text metrics" ); goto Exit; } dUpdateNow( FALSE ); if (!isCharCodingUnicode) { dprintf( "Outline Text Metrics" ); dprintf( " otmSize = %u", lpotm->otmSize ); dprintf( " otmfsSelection = 0x%.4X", lpotm->otmfsSelection ); dprintf( " otmfsType = 0x%.4X", lpotm->otmfsType ); dprintf( " otmsCharSlopeRise = %u", lpotm->otmsCharSlopeRise ); dprintf( " otmsCharSlopeRun = %u", lpotm->otmsCharSlopeRun ); dprintf( " otmItalicAngle = %d", lpotm->otmItalicAngle ); dprintf( " otmEMSquare = %u", lpotm->otmEMSquare ); dprintf( " otmAscent = %u", lpotm->otmAscent ); dprintf( " otmDescent = %d", lpotm->otmDescent ); dprintf( " otmLineGap = %u", lpotm->otmLineGap ); dprintf( " otmsXHeight = %u", lpotm->otmsXHeight ); dprintf( " otmsCapEmHeight = %u", lpotm->otmsCapEmHeight ); dprintf( " otmrcFontBox = (%d,%d)-(%d,%d)", lpotm->otmrcFontBox.left, lpotm->otmrcFontBox.top, lpotm->otmrcFontBox.right, lpotm->otmrcFontBox.bottom ); dprintf( " otmMacAscent = %u", lpotm->otmMacAscent ); dprintf( " otmMacDescent = %d", lpotm->otmMacDescent ); dprintf( " otmMacLineGap = %d", lpotm->otmMacLineGap ); dprintf( " otmusMinimumPPEM = %u", lpotm->otmusMinimumPPEM ); dprintf( " otmptSubscriptSize = (%d,%d)", lpotm->otmptSubscriptSize.x, lpotm->otmptSubscriptSize.y ); dprintf( " otmptSubscriptOffset = (%d,%d)", lpotm->otmptSubscriptOffset.x, lpotm->otmptSubscriptOffset.y ); dprintf( " otmptSuperscriptSize = (%d,%d)", lpotm->otmptSuperscriptSize.x, lpotm->otmptSuperscriptSize.y ); dprintf( " otmptSuperscriptOffset = (%d,%d)", lpotm->otmptSuperscriptOffset.x, lpotm->otmptSuperscriptOffset.y ); dprintf( " otmsStrikeoutSize = %u", lpotm->otmsStrikeoutSize ); dprintf( " otmsStrikeoutPosition = %u", lpotm->otmsStrikeoutPosition ); dprintf( " otmsUnderscoreSize = %d", lpotm->otmsUnderscoreSize ); dprintf( " otmsUnderscorePosition = %d", lpotm->otmsUnderscorePosition ); dprintf( " otmpFamilyName = '%Fs'", (LPSTR)lpotm+(WORD)lpotm->otmpFamilyName ); dprintf( " otmpFaceName = '%Fs'", (LPSTR)lpotm+(WORD)lpotm->otmpFaceName ); dprintf( " otmpStyleName = '%Fs'", (LPSTR)lpotm+(WORD)lpotm->otmpStyleName ); dprintf( " otmpFullName = '%Fs'", (LPSTR)lpotm+(WORD)lpotm->otmpFullName ); dprintf( " tmHeight = %d", lpotm->otmTextMetrics.tmHeight ); dprintf( " tmAscent = %d", lpotm->otmTextMetrics.tmAscent ); dprintf( " tmDescent = %d", lpotm->otmTextMetrics.tmDescent ); dprintf( " tmInternalLeading = %d", lpotm->otmTextMetrics.tmInternalLeading ); dprintf( " tmExternalLeading = %d", lpotm->otmTextMetrics.tmExternalLeading ); dprintf( " tmAveCharWidth = %d", lpotm->otmTextMetrics.tmAveCharWidth ); dprintf( " tmMaxCharWidth = %d", lpotm->otmTextMetrics.tmMaxCharWidth ); dprintf( " tmWeight = %d", lpotm->otmTextMetrics.tmWeight ); dprintf( " tmItalic = %d", lpotm->otmTextMetrics.tmItalic ); dprintf( " tmUnderlined = %d", lpotm->otmTextMetrics.tmUnderlined ); dprintf( " tmStruckOut = %d", lpotm->otmTextMetrics.tmStruckOut ); dprintf( " tmFirstChar = %d", lpotm->otmTextMetrics.tmFirstChar ); dprintf( " tmLastChar = %d", lpotm->otmTextMetrics.tmLastChar ); dprintf( " tmDefaultChar = %d", lpotm->otmTextMetrics.tmDefaultChar ); dprintf( " tmBreakChar = %d", lpotm->otmTextMetrics.tmBreakChar ); dprintf( " tmPitchAndFamily = 0x%.2X", lpotm->otmTextMetrics.tmPitchAndFamily ); dprintf( " tmCharSet = %d", lpotm->otmTextMetrics.tmCharSet ); dprintf( " tmOverhang = %d", lpotm->otmTextMetrics.tmOverhang ); dprintf( " tmDigitizedAspectX = %d", lpotm->otmTextMetrics.tmDigitizedAspectX ); dprintf( " tmDigitizedAspectY = %d", lpotm->otmTextMetrics.tmDigitizedAspectY ); dprintf( " " ); } else { dprintf( "Outline Text Metrics W" ); dprintf( " otmSize = %u", lpotmW->otmSize ); dprintf( " otmfsSelection = 0x%.4X", lpotmW->otmfsSelection ); dprintf( " otmfsType = 0x%.4X", lpotmW->otmfsType ); dprintf( " otmsCharSlopeRise = %u", lpotmW->otmsCharSlopeRise ); dprintf( " otmsCharSlopeRun = %u", lpotmW->otmsCharSlopeRun ); dprintf( " otmItalicAngle = %d", lpotmW->otmItalicAngle ); dprintf( " otmEMSquare = %u", lpotmW->otmEMSquare ); dprintf( " otmAscent = %u", lpotmW->otmAscent ); dprintf( " otmDescent = %d", lpotmW->otmDescent ); dprintf( " otmLineGap = %u", lpotmW->otmLineGap ); dprintf( " otmsXHeight = %u", lpotmW->otmsXHeight ); dprintf( " otmsCapEmHeight = %u", lpotmW->otmsCapEmHeight ); dprintf( " otmrcFontBox = (%d,%d)-(%d,%d)", lpotmW->otmrcFontBox.left, lpotmW->otmrcFontBox.top, lpotmW->otmrcFontBox.right, lpotmW->otmrcFontBox.bottom ); dprintf( " otmMacAscent = %u", lpotmW->otmMacAscent ); dprintf( " otmMacDescent = %d", lpotmW->otmMacDescent ); dprintf( " otmMacLineGap = %d", lpotmW->otmMacLineGap ); dprintf( " otmusMinimumPPEM = %u", lpotmW->otmusMinimumPPEM ); dprintf( " otmptSubscriptSize = (%d,%d)", lpotmW->otmptSubscriptSize.x, lpotmW->otmptSubscriptSize.y ); dprintf( " otmptSubscriptOffset = (%d,%d)", lpotmW->otmptSubscriptOffset.x, lpotmW->otmptSubscriptOffset.y ); dprintf( " otmptSuperscriptSize = (%d,%d)", lpotmW->otmptSuperscriptSize.x, lpotmW->otmptSuperscriptSize.y ); dprintf( " otmptSuperscriptOffset = (%d,%d)", lpotmW->otmptSuperscriptOffset.x, lpotmW->otmptSuperscriptOffset.y ); dprintf( " otmsStrikeoutSize = %u", lpotmW->otmsStrikeoutSize ); dprintf( " otmsStrikeoutPosition = %u", lpotmW->otmsStrikeoutPosition ); dprintf( " otmsUnderscoreSize = %d", lpotmW->otmsUnderscoreSize ); dprintf( " otmsUnderscorePosition = %d", lpotmW->otmsUnderscorePosition ); dwprintf( L" otmpFamilyName = '%Fs'", (LPWSTR)((LPSTR)lpotmW+(WORD)lpotmW->otmpFamilyName) ); dwprintf( L" otmpFaceName = '%Fs'", (LPWSTR)((LPSTR)lpotmW+(WORD)lpotmW->otmpFaceName) ); dwprintf( L" otmpStyleName = '%Fs'", (LPWSTR)((LPSTR)lpotmW+(WORD)lpotmW->otmpStyleName) ); dwprintf( L" otmpFullName = '%Fs'", (LPWSTR)((LPSTR)lpotmW+(WORD)lpotmW->otmpFullName) ); dprintf( " tmHeight = %d", lpotmW->otmTextMetrics.tmHeight ); dprintf( " tmAscent = %d", lpotmW->otmTextMetrics.tmAscent ); dprintf( " tmDescent = %d", lpotmW->otmTextMetrics.tmDescent ); dprintf( " tmInternalLeading = %d", lpotmW->otmTextMetrics.tmInternalLeading ); dprintf( " tmExternalLeading = %d", lpotmW->otmTextMetrics.tmExternalLeading ); dprintf( " tmAveCharWidth = %d", lpotmW->otmTextMetrics.tmAveCharWidth ); dprintf( " tmMaxCharWidth = %d", lpotmW->otmTextMetrics.tmMaxCharWidth ); dprintf( " tmWeight = %d", lpotmW->otmTextMetrics.tmWeight ); dprintf( " tmItalic = %d", lpotmW->otmTextMetrics.tmItalic ); dprintf( " tmUnderlined = %d", lpotmW->otmTextMetrics.tmUnderlined ); dprintf( " tmStruckOut = %d", lpotmW->otmTextMetrics.tmStruckOut ); dprintf( " tmFirstChar = %d", lpotmW->otmTextMetrics.tmFirstChar ); dprintf( " tmLastChar = %d", lpotmW->otmTextMetrics.tmLastChar ); dprintf( " tmDefaultChar = %d", lpotmW->otmTextMetrics.tmDefaultChar ); dprintf( " tmBreakChar = %d", lpotmW->otmTextMetrics.tmBreakChar ); dprintf( " tmPitchAndFamily = 0x%.2X", lpotmW->otmTextMetrics.tmPitchAndFamily ); dprintf( " tmCharSet = %d", lpotmW->otmTextMetrics.tmCharSet ); dprintf( " tmOverhang = %d", lpotmW->otmTextMetrics.tmOverhang ); dprintf( " tmDigitizedAspectX = %d", lpotmW->otmTextMetrics.tmDigitizedAspectX ); dprintf( " tmDigitizedAspectY = %d", lpotmW->otmTextMetrics.tmDigitizedAspectY ); dprintf( " " ); } dUpdateNow( TRUE ); Exit: if( lpotm ) free( lpotm ); if( lpotmW) free( lpotm ); SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); } //***************************************************************************** //******************* S H O W T E X T E X T E N T ********************* //***************************************************************************** DWORD GetCodePage(HDC hdc) { DWORD FAR *lpSrc = UlongToPtr(GetTextCharsetInfo(hdc, 0, 0)); CHARSETINFO csi; TranslateCharsetInfo(lpSrc, &csi, TCI_SRCCHARSET); return csi.ciACP; } void ShowTextExtent( HWND hwnd ) { DWORD dwrc; HDC hdc; HFONT hFont, hFontOld; ULONG i; int iSum; SIZE size; SIZE size32; ULONG len; int cch = lstrlenA(szStringA); int cwc = lstrlenW(szStringW); DWORD dwCP; hdc = CreateTestIC(); if (!isCharCodingUnicode) hFont = CreateFontIndirectWrapperA( &elfdvA ); else hFont = CreateFontIndirectWrapperW( &elfdvW ); hFontOld = SelectObject( hdc, hFont ); SetTextAlign( hdc, wTextAlign ); dwCP = GetCodePage (hdc); if (!isCharCodingUnicode) dprintf("----string byte count cch=%ld", cch); else dprintf("----unicode count cwc=%ld", cwc); if (!isCharCodingUnicode) { dprintf( "Calling GetTextExtentPointA('%s', %ld)", szStringA, cch); if (GetTextExtentPoint ( hdc, szStringA, cch, &size)) { dwrc = (DWORD) (65536 * size.cy + size.cx); dprintf( " dwrc = 0x%.8lX", dwrc ); dprintf( " width = %d", (int)size.cx); dprintf( " height = %d", (int)size.cy); } else { dprintf("GetTextExtentPointA failed"); } dprintf( "Calling GetTextExtentPoint32A('%s', %ld)", szStringA, cch); if (GetTextExtentPoint32A( hdc, szStringA, cch, &size32)) { dprintf( " width = %d", (int)size32.cx); dprintf( " height = %d", (int)size32.cy); } else { dprintf("GetTextExtentPoint32A failed"); } } else { dwprintf( L"Calling GetTextExtentPointW('%s', %ld)", szStringW, cwc); if (GetTextExtentPointW ( hdc, szStringW, cwc, &size)) { dprintf( " width = %d", (int)size.cx); dprintf( " height = %d", (int)size.cy); } else { dprintf("GetTextExtentPointW failed"); } dwprintf( L"Calling GetTextExtentPoint32W('%s', %ld)", szStringW, cwc); if (GetTextExtentPoint32W( hdc, szStringW, cwc, &size32)) { dprintf( " width = %d", (int)size32.cx); dprintf( " height = %d", (int)size32.cy); } else { dprintf("GetTextExtentPoint32W failed"); } } dprintf("----printing individual widhts:----"); // if ((cwc == cch) || (cwc == 0)) // if conversion to unicode failed { dprintf( " i : ch : width "); if (!isCharCodingUnicode) len = cch; else len = cwc; for (i = 0, iSum = 0; i < (ULONG)len; i++) { int iWidth; UINT u; if (!isCharCodingUnicode) { if (IsDBCSLeadByteEx(dwCP, szStringA[i])) { u = (UINT)(BYTE)szStringA[i]; u <<= 8; u |= (UINT)(BYTE)szStringA[i+1]; i++; } else { u = (UINT)(BYTE)szStringA[i]; } GetCharWidthA(hdc, u, u, &iWidth); } else { u = (UINT)szStringW[i]; GetCharWidthW(hdc, u, u, &iWidth); } dprintf( "%3.2d : 0x%4.2x : %3.2d", i, u, iWidth); iSum += iWidth; } } if (iSum != (int)size.cx) { dprintf("GetTextExtentPoint != Sum(CharWidths)"); dprintf( " GTE = %ld, Sum(CharWidths) = %ld", (int)size.cx, iSum ); } else { dprintf("GetTextExtentPoint == Sum(CharWidths)"); } SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); } //***************************************************************************** //******************* S H O W T E X T E X T E N T ********************* //***************************************************************************** void ShowTextExtentI( HWND hwnd ) { #ifdef GI_API DWORD dwrc; HDC hdc; HFONT hFont, hFontOld; DWORD ich, cch; SIZE size, size1; LPWORD pgi; DWORD cwc; DWORD dwCP; BYTE *pch; WCHAR *pwc; hdc = CreateTestIC(); hFont = CreateFontIndirectWrapperA( &elfdvA ); hFontOld = SelectObject( hdc, hFont ); SetTextAlign( hdc, wTextAlign ); dwCP = GetCodePage(hdc); if (!isCharCodingUnicode) { cch = (DWORD)lstrlenA(szStringA); pgi = (LPWORD)malloc(cch * sizeof(WORD)); if (pgi) { dprintf( "Calling GetGlyphIndicesA('%s')", szStringA ); if ((cwc = GetGlyphIndicesA(hdc, szStringA, cch, pgi, 0)) != GDI_ERROR) { dprintf( " ich : str : gi "); for (pch = szStringA, ich=0; ichcbThis); dprintf(" GLYPHSET.flAccel = 0x%lx", pgs->flAccel); dprintf(" GLYPHSET.cGlyphsSupported = %ld", pgs->cGlyphsSupported); dprintf(" GLYPHSET.cRanges = %ld", pgs->cRanges); dprintf(" range : [ wcLow,wcHigh] = [wcLow,wcHigh]"); for (iRun = 0; iRun < pgs->cRanges; iRun++) { dprintf(" %.5ld : [0x%.4lx,0x%.4lx] = [%.5ld,%.5ld]", iRun, pgs->ranges[iRun].wcLow, pgs->ranges[iRun].wcLow + pgs->ranges[iRun].cGlyphs - 1, pgs->ranges[iRun].wcLow, pgs->ranges[iRun].wcLow + pgs->ranges[iRun].cGlyphs - 1 ); } } } } dprintf( " dwrc = 0x%.8lX", dwrc ); SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); #endif } //***************************************************************************** //******************** S H O W T E X T F A C E ************************ //***************************************************************************** void ShowTextFace( HWND hwnd ) { int rc; HDC hdc; HFONT hFont, hFontOld; static char szFace[64]; static WCHAR szFaceW[64]; hdc = CreateTestIC(); if (!isCharCodingUnicode) hFont = CreateFontIndirectWrapperA( &elfdvA ); else hFont = CreateFontIndirectWrapperW( &elfdvW ); hFontOld = SelectObject( hdc, hFont ); SetTextAlign( hdc, wTextAlign ); dprintf( "Calling GetTextFace" ); szFace[0] = '\0'; szFaceW[0] = L'\0'; if (!isCharCodingUnicode) rc = GetTextFaceA( hdc, sizeof(szFace), szFace ); else rc = GetTextFaceW( hdc, sizeof(szFaceW)/sizeof(WCHAR), szFaceW ); dprintf( " rc = %d", rc ); if( rc ) { if (!isCharCodingUnicode) dprintf( " szFace = '%s'", szFace ); else dwprintf( L" szFaceW = '%s'", szFaceW ); } SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); } //***************************************************************************** //****************** S H O W T E X T CHARSETINFO ******************** //***************************************************************************** void ShowTextCharsetInfo(HWND hwnd) { HDC hdc; HFONT hFont, hFontOld; static FONTSIGNATURE fsig; int iCharSet; hdc = CreateTestIC(); if (!isCharCodingUnicode) hFont = CreateFontIndirectWrapperA( &elfdvA ); else hFont = CreateFontIndirectWrapperW( &elfdvW ); hFontOld = SelectObject( hdc, hFont ); if( (iCharSet = GetTextCharsetInfo( hdc, &fsig, 0)) == DEFAULT_CHARSET) { dprintf( " Error getting TextCharsetInfo" ); goto Exit; } dUpdateNow( FALSE ); dprintf( "GetTextCharsetInfo" ); dprintf( " rc = %ld",iCharSet); dprintf( "FONTSIGNATURE:" ); dprintf( " fsUsb[0] = 0x%lx", fsig.fsUsb[0]); dprintf( " fsUsb[1] = 0x%lx", fsig.fsUsb[1]); dprintf( " fsUsb[2] = 0x%lx", fsig.fsUsb[2]); dprintf( " fsUsb[3] = 0x%lx", fsig.fsUsb[3]); dprintf( " fsCsb[0] = 0x%lx", fsig.fsCsb[0]); dprintf( " fsCsb[1] = 0x%lx", fsig.fsCsb[1]); dprintf( " " ); //ANSI bitfields if ( fsig.fsCsb[0] != 0 ) dprintf( " fsCsb[0]:"); if (fsig.fsCsb[0] & CPB_LATIN1_ANSI) dprintf( " %s", "Latin1 ANSI"); if (fsig.fsCsb[0] & CPB_LATIN2_EASTEU) dprintf( " %s", "Latin2 Eastern Europe"); if (fsig.fsCsb[0] & CPB_CYRILLIC_ANSI) dprintf( " %s", "Cyrillic ANSI"); if (fsig.fsCsb[0] & CPB_GREEK_ANSI) dprintf( " %s", "Greek ANSI"); if (fsig.fsCsb[0] & CPB_TURKISH_ANSI) dprintf( " %s", "Turkish ANSI"); if (fsig.fsCsb[0] & CPB_HEBREW_ANSI) dprintf( " %s", "Hebrew ANSI"); if (fsig.fsCsb[0] & CPB_ARABIC_ANSI) dprintf( " %s", "Arabic ANSI"); if (fsig.fsCsb[0] & CPB_BALTIC_ANSI) dprintf( " %s", "Baltic ANSI"); //ANSI & OEM bitfields if (fsig.fsCsb[0] & CPB_THAI) dprintf( " %s", "Thai"); if (fsig.fsCsb[0] & CPB_JIS_JAPAN) dprintf( " %s", "JIS/Japan"); if (fsig.fsCsb[0] & CPB_CHINESE_SIMP) dprintf( " %s", "Chinese Simplified"); if (fsig.fsCsb[0] & CPB_KOREAN_WANSUNG) dprintf( " %s", "Korean Wansung"); if (fsig.fsCsb[0] & CPB_CHINESE_TRAD) dprintf( " %s", "Chinese Traditional"); if (fsig.fsCsb[0] & CPB_KOREAN_JOHAB) dprintf( " %s", "Korean Johab"); if (fsig.fsCsb[0] & CPB_MACINTOSH_CHARSET) dprintf( " %s", "Macintosh Character Set"); if (fsig.fsCsb[0] & CPB_OEM_CHARSET) dprintf( " %s", "OEM Character Set"); if (fsig.fsCsb[0] & CPB_SYMBOL_CHARSET) dprintf( " %s", "Symbol Character Set"); dprintf( " "); // OEM bitfields if ( fsig.fsCsb[1] != 0 ) dprintf( "fsCsb[1]:"); if (fsig.fsCsb[1] & CPB_IBM_GREEK) dprintf( " %s", "IBM Greek"); if (fsig.fsCsb[1] & CPB_MSDOS_RUSSIAN) dprintf( " %s", "MS-DOS Russian"); if (fsig.fsCsb[1] & CPB_MSDOS_NORDIC) dprintf( " %s", "MS-DOS Nordic"); if (fsig.fsCsb[1] & CPB_ARABIC_OEM) dprintf( " %s", "Arabic OEM"); if (fsig.fsCsb[1] & CPB_MSDOS_CANADIANFRE) dprintf( " %s", "MS-DOS Canadian French"); if (fsig.fsCsb[1] & CPB_HEBREW_OEM) dprintf( " %s", "Hebrew OEM"); if (fsig.fsCsb[1] & CPB_MSDOS_ICELANDIC) dprintf( " %s", "MS-DOS Icelandic"); if (fsig.fsCsb[1] & CPB_MSDOS_PORTUGUESE) dprintf( " %s", "MS-DOS Portuguese"); if (fsig.fsCsb[1] & CPB_IBM_TURKISH) dprintf( " %s", "IBM Turkish"); if (fsig.fsCsb[1] & CPB_IBM_CYRILLIC) dprintf( " %s", "IBM Cyrillic"); if (fsig.fsCsb[1] & CPB_LATIN2_OEM) dprintf( " %s", "Latin2 OEM"); if (fsig.fsCsb[1] & CPB_BALTIC_OEM) dprintf( " %s", "Baltic OEM"); if (fsig.fsCsb[1] & CPB_GREEK_OEM) dprintf( " %s", "Greek OEM"); if (fsig.fsCsb[1] & CPB_ARABIC_OEM) dprintf( " %s", "Arabic OEM"); if (fsig.fsCsb[1] & CPB_WE_LATIN1) dprintf( " %s", "WE/Latin1"); if (fsig.fsCsb[1] & CPB_US_OEM) dprintf( " %s", "US OEM"); dprintf( " "); // fsUsb[0] fields if ( fsig.fsUsb[0] != 0 ) dprintf(" fsUsb[0]:"); if (fsig.fsUsb[0] & USB_BASIC_LATIN) dprintf( " %s", "Basic Latin"); if (fsig.fsUsb[0] & USB_LATIN1_SUPPLEMENT) dprintf( " %s", "Latin-1 Supplement"); if (fsig.fsUsb[0] & USB_LATIN_EXTENDEDA) dprintf( " %s", "Latin Extended-A"); if (fsig.fsUsb[0] & USB_LATIN_EXTENDEDB) dprintf( " %s", "Latin Extended-B"); if (fsig.fsUsb[0] & USB_IPA_EXTENSIONS) dprintf( " %s", "IPA Extensions"); if (fsig.fsUsb[0] & USB_SPACE_MODIF_LETTER) dprintf( " %s", "Spacing Modifier Letters"); if (fsig.fsUsb[0] & USB_COMB_DIACR_MARKS) dprintf( " %s", "Combining Diacritical Marks"); if (fsig.fsUsb[0] & USB_BASIC_GREEK) dprintf( " %s", "Basic Greek"); if (fsig.fsUsb[0] & USB_GREEK_SYM_COPTIC) dprintf( " %s", "Greek Symbols Marks"); if (fsig.fsUsb[0] & USB_CYRILLIC) dprintf( " %s", "Cyrillic"); if (fsig.fsUsb[0] & USB_ARMENIAN) dprintf( " %s", "Armenian"); if (fsig.fsUsb[0] & USB_BASIC_HEBREW) dprintf( " %s", "Basic Hebrew"); if (fsig.fsUsb[0] & USB_HEBREW_EXTENDED) dprintf( " %s", "Hebrew Extended"); if (fsig.fsUsb[0] & USB_BASIC_ARABIC) dprintf( " %s", "Basic Arabic"); if (fsig.fsUsb[0] & USB_ARABIC_EXTENDED) dprintf( " %s", "Arabic Extended"); if (fsig.fsUsb[0] & USB_DEVANAGARI) dprintf( " %s", "Devanagari"); if (fsig.fsUsb[0] & USB_BENGALI) dprintf( " %s", "Bengali"); if (fsig.fsUsb[0] & USB_GURMUKHI) dprintf( " %s", "Gurmukhi"); if (fsig.fsUsb[0] & USB_GUJARATI) dprintf( " %s", "Gujarati"); if (fsig.fsUsb[0] & USB_ORIYA) dprintf( " %s", "Oriya"); if (fsig.fsUsb[0] & USB_TAMIL) dprintf( " %s", "Tamil"); if (fsig.fsUsb[0] & USB_TELUGU) dprintf( " %s", "Telugu"); if (fsig.fsUsb[0] & USB_KANNADA) dprintf( " %s", "Kannada"); if (fsig.fsUsb[0] & USB_MALAYALAM) dprintf( " %s", "Malayalam"); if (fsig.fsUsb[0] & USB_THAI) dprintf( " %s", "Thai"); if (fsig.fsUsb[0] & USB_LAO) dprintf( " %s", "Lao"); if (fsig.fsUsb[0] & USB_BASIC_GEORGIAN) dprintf( " %s", "Basic Georgian"); if (fsig.fsUsb[0] & USB_HANGUL_JAMO) dprintf( " %s", "Hangul Jamo"); if (fsig.fsUsb[0] & USB_LATIN_EXT_ADD) dprintf( " %s", "Latin Extended Additional"); if (fsig.fsUsb[0] & USB_GREEK_EXTENDED) dprintf( " %s", "Greek Extended"); if (fsig.fsUsb[0] & USB_GEN_PUNCTUATION) dprintf( " %s", "General Punctuation"); dprintf( " "); // fsUsb[1] fields if ( fsig.fsUsb[1] != 0) dprintf(" fsUsb[1]:"); if (fsig.fsUsb[1] & USB_SUPER_SUBSCRIPTS) dprintf( " %s", "Superscripts and Subscripts"); if (fsig.fsUsb[1] & USB_CURRENCY_SYMBOLS) dprintf( " %s", "Currency Symbols"); if (fsig.fsUsb[1] & USB_COMB_DIACR_MARK_SYM) dprintf( " %s", "Combining diacritical Marks For Symbols"); if (fsig.fsUsb[1] & USB_LETTERLIKE_SYMBOL) dprintf( " %s", "Letterlike Symbols"); if (fsig.fsUsb[1] & USB_NUMBER_FORMS) dprintf( " %s", "Number Forms"); if (fsig.fsUsb[1] & USB_ARROWS) dprintf( " %s", "Arrows"); if (fsig.fsUsb[1] & USB_MATH_OPERATORS) dprintf( " %s", "Mathematical Operators"); if (fsig.fsUsb[1] & USB_MISC_TECHNICAL) dprintf( " %s", "Miscellaneous Technical"); if (fsig.fsUsb[1] & USB_CONTROL_PICTURE) dprintf( " %s", "Control Pictures"); if (fsig.fsUsb[1] & USB_OPT_CHAR_RECOGNITION) dprintf( " %s", "Optical Character Recognition"); if (fsig.fsUsb[1] & USB_ENCLOSED_ALPHANUMERIC) dprintf( " %s", "Enclosed Alphanumerics"); if (fsig.fsUsb[1] & USB_BOX_DRAWING) dprintf( " %s", "Box Drawing"); if (fsig.fsUsb[1] & USB_BLOCK_ELEMENTS) dprintf( " %s", "Block Elements"); if (fsig.fsUsb[1] & USB_GEOMETRIC_SHAPE) dprintf( " %s", "Geometric Shape"); if (fsig.fsUsb[1] & USB_MISC_SYMBOLS) dprintf( " %s", "Geometric Shapes"); if (fsig.fsUsb[1] & USB_DINGBATS) dprintf( " %s", "Dingbats"); if (fsig.fsUsb[1] & USB_CJK_SYM_PUNCTUATION) dprintf( " %s", "CJK Symbols and Punctuation"); if (fsig.fsUsb[1] & USB_HIRAGANA) dprintf( " %s", "Hiragana"); if (fsig.fsUsb[1] & USB_KATAKANA) dprintf( " %s", "Katakana"); if (fsig.fsUsb[1] & USB_BOPOMOFO) dprintf( " %s", "Bopomofo"); if (fsig.fsUsb[1] & USB_HANGUL_COMP_JAMO) dprintf( " %s", "Hangul Compatibility Jamo"); if (fsig.fsUsb[1] & USB_CJK_MISCELLANEOUS) dprintf( " %s", "CJK Miscellaneous"); if (fsig.fsUsb[1] & USB_EN_CJK_LETTER_MONTH) dprintf( " %s", "Enclosed CJK letters And Months"); if (fsig.fsUsb[1] & USB_CJK_COMPATIBILITY) dprintf( " %s", "CJK Compatibility"); if (fsig.fsUsb[1] & USB_HANGUL) dprintf( " %s", "Hangul"); if (fsig.fsUsb[1] & USB_CJK_UNIFY_IDEOGRAPH) dprintf( " %s", "CJK Unified Ideographs"); if (fsig.fsUsb[1] & USB_PRIVATE_USE_AREA) dprintf( " %s", "Private Use Area"); if (fsig.fsUsb[1] & USB_CJK_COMP_IDEOGRAPH) dprintf( " %s", "CJK Compatibility Ideographs"); if (fsig.fsUsb[1] & USB_ALPHA_PRES_FORMS) dprintf( " %s", "Alphabetic Presentation Forms"); if (fsig.fsUsb[1] & USB_ARABIC_PRES_FORMA) dprintf( " %s", "Arabic Presentation Forms-A"); dprintf( " "); // fsUsb[2] field if ( fsig.fsUsb[2] != 0 ) dprintf(" fsUsb[2]:"); if (fsig.fsUsb[2] & USB_COMB_HALF_MARK) dprintf( " %s", "Combining Half Marks"); if (fsig.fsUsb[2] & USB_CJK_COMP_FORMS) dprintf( " %s", "CJK Compatibility Forms"); if (fsig.fsUsb[2] & USB_SMALL_FORM_VARIANTS) dprintf( " %s", "Small Form Variants"); if (fsig.fsUsb[2] & USB_ARABIC_PRES_FORMB) dprintf( " %s", "Arabic Presentation Forms-B"); if (fsig.fsUsb[2] & USB_HALF_FULLWIDTH_FORM) dprintf( " %s", "Halfwidth And Fullwidth Forms"); if (fsig.fsUsb[2] & USB_SPECIALS) dprintf( " %s", "Specials"); dUpdateNow( TRUE ); Exit: SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); } typedef struct { char *Description; DWORD Flag; } FLI_STRINGS; FLI_STRINGS Test[] = { {"GCP_DBCS", GCP_DBCS}, {"GCP_DIACRITIC", GCP_DIACRITIC}, {"GCP_GLYPHSHAPE", GCP_GLYPHSHAPE}, {"GCP_KASIDHA", GCP_KASHIDA}, {"GCP_LIGATE", GCP_LIGATE}, {"GCP_USEKERNING", GCP_USEKERNING}, {"GCP_REORDER", GCP_REORDER}, {"FLI_GLYPHS", FLI_GLYPHS} }; void ShowFontLanguageInfo(HWND hwnd) { HDC hdc; HFONT hFont, hFontOld; static FONTSIGNATURE fsig; int i; DWORD dwFLI; hdc = CreateTestIC(); if (!isCharCodingUnicode) hFont = CreateFontIndirectWrapperA( &elfdvA ); else hFont = CreateFontIndirectWrapperW( &elfdvW ); hFontOld = SelectObject( hdc, hFont ); if((dwFLI = GetFontLanguageInfo( hdc )) == GCP_ERROR) { dprintf( " Error getting FontLanguageInfo" ); goto Exit; } dUpdateNow( FALSE ); dprintf("GetFontLanguageInfo rc = 0x%x", dwFLI); for( i = 0; i < sizeof(Test) / sizeof(FLI_STRINGS); i++) { if( dwFLI & Test[i].Flag ) { dprintf( Test[i].Description ); } } dprintf( " " ); dUpdateNow( TRUE ); Exit: SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); } //***************************************************************************** //****************** S H O W T E X T M E T R I C S ******************** //***************************************************************************** void ShowTextMetrics( HWND hwnd ) { HDC hdc; HFONT hFont, hFontOld; static TEXTMETRIC tm; static TEXTMETRICW tmW; BOOL isOK; BYTE bFamilyInfo; hdc = CreateTestIC(); if (!isCharCodingUnicode) hFont = CreateFontIndirectWrapperA( &elfdvA ); else hFont = CreateFontIndirectWrapperW( &elfdvW ); hFontOld = SelectObject( hdc, hFont ); SetTextAlign( hdc, wTextAlign ); if (!isCharCodingUnicode) isOK = GetTextMetricsA( hdc, &tm ); else isOK = GetTextMetricsW( hdc, &tmW ); if(!isOK) { dprintf( " Error getting text metrics" ); goto Exit; } dUpdateNow( FALSE ); if (!isCharCodingUnicode) { dprintf( "Text Metrics" ); dprintf( " tmHeight = %d", tm.tmHeight ); dprintf( " tmAscent = %d", tm.tmAscent ); dprintf( " tmDescent = %d", tm.tmDescent ); dprintf( " tmInternalLeading = %d", tm.tmInternalLeading ); dprintf( " tmExternalLeading = %d", tm.tmExternalLeading ); dprintf( " tmAveCharWidth = %d", tm.tmAveCharWidth ); dprintf( " tmMaxCharWidth = %d", tm.tmMaxCharWidth ); dprintf( " tmWeight = %d", tm.tmWeight ); dprintf( " tmItalic = %d", tm.tmItalic ); dprintf( " tmUnderlined = %d", tm.tmUnderlined ); dprintf( " tmStruckOut = %d", tm.tmStruckOut ); dprintf( " tmFirstChar = %d", tm.tmFirstChar ); dprintf( " tmLastChar = %d", tm.tmLastChar ); dprintf( " tmDefaultChar = %d", tm.tmDefaultChar ); dprintf( " tmBreakChar = %d", tm.tmBreakChar ); dprintf( " tmPitchAndFamily = 0x%.2X", tm.tmPitchAndFamily ); dprintf( " tmCharSet = %d", tm.tmCharSet ); dprintf( " tmOverhang = %d", tm.tmOverhang ); dprintf( " tmDigitizedAspectX = %d", tm.tmDigitizedAspectX ); dprintf( " tmDigitizedAspectY = %d", tm.tmDigitizedAspectY ); dprintf( " " ); dprintf( " Flags set for Pitch and Family:"); if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH) dprintf(" TMPF_FIXED_PITCH (meaning variable)"); if (tm.tmPitchAndFamily & TMPF_VECTOR) dprintf(" TMPF_VECTOR"); if (tm.tmPitchAndFamily & TMPF_DEVICE) dprintf(" TMPF_DEVICE"); if (tm.tmPitchAndFamily & TMPF_TRUETYPE) dprintf(" TMPF_TRUETYPE"); bFamilyInfo = tm.tmPitchAndFamily & 0xF0; switch(bFamilyInfo) { case FF_ROMAN : dprintf(" FF_ROMAN"); break; case FF_SWISS : dprintf(" FF_SWISS"); break; case FF_MODERN : dprintf(" FF_MODERN"); break; case FF_SCRIPT : dprintf(" FF_SCRIPT"); break; case FF_DECORATIVE : dprintf(" FF_DECORATIVE"); break; default : dprintf(" FF_UNKNOWN"); } } else { dprintf( "Text Metrics" ); dprintf( " tmHeight = %d", tmW.tmHeight ); dprintf( " tmAscent = %d", tmW.tmAscent ); dprintf( " tmDescent = %d", tmW.tmDescent ); dprintf( " tmInternalLeading = %d", tmW.tmInternalLeading ); dprintf( " tmExternalLeading = %d", tmW.tmExternalLeading ); dprintf( " tmAveCharWidth = %d", tmW.tmAveCharWidth ); dprintf( " tmMaxCharWidth = %d", tmW.tmMaxCharWidth ); dprintf( " tmWeight = %d", tmW.tmWeight ); dprintf( " tmItalic = %d", tmW.tmItalic ); dprintf( " tmUnderlined = %d", tmW.tmUnderlined ); dprintf( " tmStruckOut = %d", tmW.tmStruckOut ); dprintf( " tmFirstChar = %d", tmW.tmFirstChar ); dprintf( " tmLastChar = %d", tmW.tmLastChar ); dprintf( " tmDefaultChar = %d", tmW.tmDefaultChar ); dprintf( " tmBreakChar = %d", tmW.tmBreakChar ); dprintf( " tmPitchAndFamily = 0x%.2X", tmW.tmPitchAndFamily ); dprintf( " tmCharSet = %d", tmW.tmCharSet ); dprintf( " tmOverhang = %d", tmW.tmOverhang ); dprintf( " tmDigitizedAspectX = %d", tmW.tmDigitizedAspectX ); dprintf( " tmDigitizedAspectY = %d", tmW.tmDigitizedAspectY ); dprintf( " " ); dprintf( " Flags set for Pitch and Family:"); if (tmW.tmPitchAndFamily & TMPF_FIXED_PITCH) dprintf(" TMPF_FIXED_PITCH (meaning variable)"); if (tmW.tmPitchAndFamily & TMPF_VECTOR) dprintf(" TMPF_VECTOR"); if (tmW.tmPitchAndFamily & TMPF_DEVICE) dprintf(" TMPF_DEVICE"); if (tmW.tmPitchAndFamily & TMPF_TRUETYPE) dprintf(" TMPF_TRUETYPE"); bFamilyInfo = tmW.tmPitchAndFamily & 0xF0; switch(bFamilyInfo) { case FF_ROMAN : dprintf(" FF_ROMAN"); break; case FF_SWISS : dprintf(" FF_SWISS"); break; case FF_MODERN : dprintf(" FF_MODERN"); break; case FF_SCRIPT : dprintf(" FF_SCRIPT"); break; case FF_DECORATIVE : dprintf(" FF_DECORATIVE"); break; default : dprintf(" FF_UNKNOWN"); } } dUpdateNow( TRUE ); Exit: SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); } //***************************************************************************** //****************** S H O W CHAR WIDTH INFO ******************** //***************************************************************************** #ifdef USERGETCHARWIDTH void ShowCharWidthInfo( HANDLE hwnd ) { HDC hdc; HFONT hFont, hFontOld; CHWIDTHINFO ChWidthInfo; hdc = CreateTestIC(); hFont = CreateFontIndirectWrapperA( &elfdvA ); hFontOld = SelectObject( hdc, hFont ); dUpdateNow( FALSE ); if ( GetCharWidthInfo(hdc, &ChWidthInfo) ) { dprintf( " Calling GetCharWidthInfo "); dprintf( " lMaxNegA: = %ld", ChWidthInfo.lMaxNegA ); dprintf( " lMaxNegC: = %ld", ChWidthInfo.lMaxNegC ); dprintf( " lMinWidthD: = %ld", ChWidthInfo.lMinWidthD ); dprintf( " "); } else { dprintf( "Error getting CharWidthInfo"); dprintf( " "); } dUpdateNow( TRUE ); SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); } #endif //USERGETCHARWIDTH //***************************************************************************** //********************* S H O W GETKERNINGPAIRS ************************* //***************************************************************************** void GetKerningPairsDlgProc( HWND hwnd ) { HDC hdc; HFONT hFont, hFontOld; DWORD nNumKernPairs, dwRet, i; LPKERNINGPAIR lpKerningPairs; hdc = CreateTestIC(); hFont = CreateFontIndirectWrapperA( &elfdvA ); hFontOld = SelectObject( hdc, hFont ); nNumKernPairs = GetKerningPairs(hdc, 0, NULL); dUpdateNow( FALSE ); dprintf( ""); dprintf( " GetKerningPairs:" ); dprintf( " total number of kerning pairs = %ld", nNumKernPairs); if (nNumKernPairs) { lpKerningPairs = (LPKERNINGPAIR) malloc(sizeof(KERNINGPAIR) * nNumKernPairs); dwRet = GetKerningPairs(hdc, nNumKernPairs, lpKerningPairs); dprintf( " First Second Amount"); dprintf( " ======= ======== ========"); for(i=0; ilfFaceName, iPointSize); // prepare logfont for a non-antialiased font. hdc = CreateTestIC(); memcpy(&lfNormal, lf, sizeof(LOGFONTA)); lfNormal.lfQuality = NONANTIALIASED_QUALITY; lfNormal.lfHeight = -MulDiv(iPointSize, GetDeviceCaps(hdc, LOGPIXELSY), 72); // create dc's. hFont = CreateFontIndirectA(&lfNormal); hFontOld = SelectObject( hdc, hFont ); // prepare logfont for an antialiased font. hdcAntiAliased = CreateTestIC(); memcpy(&lfAntiAliased, lf, sizeof(LOGFONTA)); lfAntiAliased.lfQuality = CLEARTYPE_QUALITY; lfAntiAliased.lfHeight = -MulDiv(iPointSize, GetDeviceCaps(hdcAntiAliased, LOGPIXELSY), 72); hdcAntiAliased = CreateTestIC(); hFontAntiAliased = CreateFontIndirectA(&lfAntiAliased); hFontOldAntiAliased = SelectObject( hdcAntiAliased, hFontAntiAliased ); // Get the size of the the GLYPHSET first. if (iSize = GetFontUnicodeRanges(hdc, NULL)) { if (lpgsFont = GlobalAlloc(GPTR, iSize)) { if (GetFontUnicodeRanges(hdc, (LPGLYPHSET) lpgsFont)) { for (iRun = 0; iRun < lpgsFont->cRanges; iRun++) { for (wUnicodePoint = lpgsFont->ranges[iRun].wcLow; wUnicodePoint < lpgsFont->ranges[iRun].wcLow + (UINT) lpgsFont->ranges[iRun].cGlyphs; wUnicodePoint ++) { // get char widths for two modes. GetCharWidth32W(hdc, wUnicodePoint, wUnicodePoint, &iCharWidthNormal); GetCharWidth32W(hdcAntiAliased, wUnicodePoint, wUnicodePoint, &iCharWidthAntiAlias); // dprintf(" Char %x Widths: %d %d ", wUnicodePoint, iCharWidthNormal, iCharWidthAntiAlias); if (iCharWidthNormal != iCharWidthAntiAlias) { fDiff = TRUE; dprintf(" Mismatching widths: Char %x Widths - %d : %d ", wUnicodePoint, iCharWidthNormal, iCharWidthAntiAlias); } // get char abc widths for two modes. if (GetCharABCWidthsW(hdc, wUnicodePoint, wUnicodePoint, &abcCharWidthNormal)) { GetCharABCWidthsW(hdcAntiAliased, wUnicodePoint, wUnicodePoint, &abcCharWidthAntiAlias); iCharWidthNormal = abcCharWidthNormal.abcA + abcCharWidthNormal.abcB + abcCharWidthNormal.abcC; iCharWidthAntiAlias = abcCharWidthAntiAlias.abcA + abcCharWidthAntiAlias.abcB + abcCharWidthAntiAlias.abcC; if (iCharWidthNormal != iCharWidthAntiAlias) { fDiff = TRUE; dprintf(" Mismatching widths: Char %x Widths - %d : %d ", wUnicodePoint, iCharWidthNormal, iCharWidthAntiAlias); //dprintf(" Mismatching widths: Char %x ABC Widths - (%d %d %d) (%d %d %d)", wUnicodePoint, // abcCharWidthNormal.abcA, abcCharWidthNormal.abcB,abcCharWidthNormal.abcC, // abcCharWidthAntiAlias.abcA, abcCharWidthAntiAlias.abcB, abcCharWidthAntiAlias.abcC); } } } } if (!fDiff) dprintf(" No char width differences found! "); } GlobalFree(lpgsFont); } } } // cleanup dc's SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); SelectObject( hdcAntiAliased, hFontOldAntiAliased ); DeleteObject( hFontAntiAliased ); DeleteTestIC( hdcAntiAliased ); return; #endif } //***************************************************************************** //****************** EnumFontFamProcExCharWidth ************************* //***************************************************************************** int CALLBACK EnumFontFamProcExCharWidth(ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, int FontType, LPARAM lParam) { HWND hwnd = (HWND) lParam; CharWidthTestForAntiAliasing(hwnd, &(lpelfe->elfLogFont)); // continue enumeration return TRUE; } //***************************************************************************** //**************** CharWidthTestAllForAntiAliasing ********************** //***************************************************************************** void CharWidthTestAllForAntiAliasing( HWND hwnd ) { LOGFONT lf; HDC hdc; hdc = CreateTestIC(); lf.lfCharSet = ANSI_CHARSET; lstrcpy(lf.lfFaceName, TEXT("")); lf.lfPitchAndFamily = 0; EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC) EnumFontFamProcExCharWidth, (LPARAM) hwnd, 0); DeleteTestIC( hdc ); } #ifdef GI_API void TextOutPerformanceInternal( HWND hwnd, BYTE lfQuality ) { HDC hdc; HFONT hFontOld; DWORD i, j; int oldHeight; _int64 liStart; _int64 liTotal, liBigTotal; _int64 liFreq; _int64 liNow; ULONG liDelta; BYTE jOldQuality; char szTestStringA[63] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; WCHAR szTestStringW[63] = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; #define TestSizes 20 #define MinEmHeight 8 #define LoopCount 20 HFONT ahFont[TestSizes]; hdc = CreateTestIC(); if (!isCharCodingUnicode) { oldHeight = elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight; elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = -9; jOldQuality = elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality; elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality = lfQuality; } else { oldHeight = elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight; elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight = -9; jOldQuality = elfdvW.elfEnumLogfontEx.elfLogFont.lfQuality; elfdvW.elfEnumLogfontEx.elfLogFont.lfQuality = lfQuality; } for (i = 0; i < TestSizes; i++) { if (!isCharCodingUnicode) { ahFont[i] = CreateFontIndirectWrapperA( &elfdvA ); elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight --; } else { ahFont[i] = CreateFontIndirectWrapperW( &elfdvW ); elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight --; } } hFontOld = SelectObject( hdc, ahFont[0] ); QueryPerformanceFrequency((LARGE_INTEGER *) &liFreq); dUpdateNow( FALSE ); liBigTotal = 0; dprintf( ""); for (j = 0; j < 5; j++) { FlushFontCache(hdc); if (!isCharCodingUnicode) { QueryPerformanceCounter((LARGE_INTEGER *) &liStart); for (i = 0; i < TestSizes; i++) { SelectObject( hdc, ahFont[i] ); TextOutA(hdc,0,100,szTestStringA,62); } QueryPerformanceCounter((LARGE_INTEGER *) &liNow); } else { QueryPerformanceCounter((LARGE_INTEGER *) &liStart); for (i = 0; i < TestSizes; i++) { SelectObject( hdc, ahFont[i] ); TextOutW(hdc,0,100,szTestStringW,62); } QueryPerformanceCounter((LARGE_INTEGER *) &liNow); } liTotal = liNow - liStart; liBigTotal += liTotal; liDelta = (ULONG) ((liTotal * 1000) / liFreq); dprintf( " Time[%d] : %d millisec",j,liDelta ); } if (!isCharCodingUnicode) { elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = oldHeight; elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality = jOldQuality; } else { elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight = oldHeight; elfdvW.elfEnumLogfontEx.elfLogFont.lfQuality = jOldQuality; } liDelta = (ULONG) ((liBigTotal * 1000) / liFreq); dprintf( " TextOutPerformance :" ); dprintf( " TotalTime : %d millisec",liDelta ); dUpdateNow( TRUE ); SelectObject( hdc, hFontOld ); for (i = 0; i < TestSizes; i++) { DeleteObject(ahFont[i]); } DeleteTestIC( hdc ); } void TextOutPerformance( HWND hwnd) { DWORD dwOldBatchLimit = GdiSetBatchLimit(1); // zero means default ie 20 dprintf(" Monochrome Text:"); TextOutPerformanceInternal(hwnd, NONANTIALIASED_QUALITY); dprintf(" "); dprintf(" AA/CT Text:"); TextOutPerformanceInternal(hwnd, ANTIALIASED_QUALITY); GdiSetBatchLimit(dwOldBatchLimit); // zero means default ie 20 #if 0 // blend macros for cleartype #define DIVIDE(A,B) ( ((A)+(B)/2) / (B) ) // blend macros for cleartype // this is k/6, k = 0,1,...,6 in 12.20 format // Why 12.20 ? well, we are tring to store 6*256 = 1536 = 600h. // (the largest possible result of multiplying k*dB), // this fits in eleven bits, so just to be safe we allow 12 bits for // integer part and 20 bits for the fractional part. // By using this we avoid doing divides by 6 in trasparent cases and // in computation of ct lookup table LONG alAlpha[7] = { 0, DIVIDE(1L << 20, 6), DIVIDE(2L << 20, 6), DIVIDE(3L << 20, 6), DIVIDE(4L << 20, 6), DIVIDE(5L << 20, 6), DIVIDE(6L << 20, 6), }; #define HALF20 (1L << 19) // #define ROUND20(X) (((X) + HALF20) >> 20) #define ROUND20(X) ((X) >> 20) #define BLEND(k,B,dB) ((B) + ROUND20(alAlpha[k] * (dB))) #define BLENDCT(k,F,B,dB) (ULONG)(((k) == 0) ? (B) : (((k) == 6) ? (F) : BLEND(k,B,dB))) #define BLENDOLD(k,F,B) (ULONG)DIVIDE((k) * (F) + (6 - (k)) * (B), 6) LONG b,f; ULONG fnew, fold; BYTE k; ULONG ulTotal = 0, ulError = 0, ulPercent; dprintf("begin !!!"); for (f = 0; f < 256; f++) { for (b = 0; b < 256; b++) { for (k = 0; k <= 6; k++) { fold = BLENDOLD(k,f,b); fnew = BLEND(k, b, (f-b)); if (fold > 256) dprintf("fold > 256, k = %d, f = %d, b = %d, fold = %ld", k, f, b, fold); if (fnew > 256) dprintf("fnew > 256, k = %d, f = %d, b = %d, fnew = %ld", k, f, b, fnew); if (fnew != fold) { LONG diff = (LONG)fold - (LONG)fnew; if (diff < 0) diff = -diff; if (diff > 1) { dprintf("fnew != fold, k: %d, f: %d, b: %d, fnew: 0x%lx, fold: 0x%lx, diff: 0x%lx", k, f, b, fnew, fold, diff); } ulError++; } ulTotal++; } } } ulPercent = DIVIDE(ulError * 100 , ulTotal); dprintf("done !!! ulTotal = %ld, ulError = %ld, wrong in %ld percent cases", ulTotal, ulError, ulPercent); #endif } char szTestStringA[63] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; WCHAR szTestStringW[63] = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; _int64 ClearTypePerformanceLoopA(HWND hwnd , HDC hdc) { DWORD i, j; int y; TEXTMETRIC tm; _int64 liStart; _int64 liNow; _int64 liTotal = 0; HFONT hFont, hOldFont; for (i = 0; i < TestSizes; i++) { hFont = CreateFontIndirectWrapperA( &elfdvA ); hOldFont = SelectObject( hdc, hFont ); GetTextMetrics( hdc, &tm ); y = 50; TextOutA(hdc,5,0,szTestStringA,62); DrawDCAxis( hwnd, hdc, FALSE); QueryPerformanceCounter((LARGE_INTEGER *) &liStart); for (j = 0; j < LoopCount; j++) { TextOutA(hdc,5, y,szTestStringA,62); y += tm.tmHeight; } QueryPerformanceCounter((LARGE_INTEGER *) &liNow); liTotal += (liNow - liStart); elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight --; SelectObject( hdc, hOldFont ); DeleteObject(hFont); } return liTotal; } _int64 ClearTypePerformanceLoopW(HWND hwnd , HDC hdc) { DWORD i, j; int y; TEXTMETRIC tm; _int64 liStart; _int64 liNow; _int64 liTotal = 0; HFONT hFont, hOldFont; for (i = 0; i < TestSizes; i++) { hFont = CreateFontIndirectWrapperW( &elfdvW ); hOldFont = SelectObject( hdc, hFont ); GetTextMetrics( hdc, &tm ); y = 50; TextOutW(hdc,5,0,szTestStringW,62); DrawDCAxis( hwnd, hdc, FALSE); QueryPerformanceCounter((LARGE_INTEGER *) &liStart); for (j = 0; j < LoopCount; j++) { TextOutW(hdc,5, y,szTestStringW,62); y += tm.tmHeight; } QueryPerformanceCounter((LARGE_INTEGER *) &liNow); liTotal += (liNow - liStart); elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight --; SelectObject( hdc, hOldFont ); DeleteObject(hFont); } return liTotal; } void ClearTypePerformanceInternal( HWND hwnd, BYTE jQuality ) { HDC hdc; int oldHeight; BYTE oldQuality; _int64 liTotal, liBigTotal; _int64 liFreq; ULONG liDelta; BOOL oldIsGradientBackground = isGradientBackground; // hdc = CreateTestIC(); hdc = GetDC(hwnd); if (!isCharCodingUnicode) { oldHeight = elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight; oldQuality = elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality; } else { oldHeight = elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight; oldQuality = elfdvW.elfEnumLogfontEx.elfLogFont.lfQuality; } QueryPerformanceFrequency((LARGE_INTEGER *) &liFreq); dUpdateNow( FALSE ); liBigTotal = 0; dprintf( ""); if (!isCharCodingUnicode) { SetBkMode( hdc, OPAQUE ); isGradientBackground = FALSE; elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality = jQuality; elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = -MinEmHeight; liTotal = ClearTypePerformanceLoopA(hwnd , hdc); liBigTotal += liTotal; liDelta = (ULONG) ((liTotal * 1000) / liFreq); dprintf( " Opaque Time[%d] : %d millisec",LoopCount,liDelta ); /* antialiazed transparent: */ SetBkMode( hdc, TRANSPARENT ); elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality = jQuality; elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = -MinEmHeight; liTotal = ClearTypePerformanceLoopA(hwnd , hdc); liBigTotal += liTotal; liDelta = (ULONG) ((liTotal * 1000) / liFreq); dprintf( " Trsp Solid Time[%d] : %d millisec",LoopCount,liDelta ); /* antialiazed transparent: */ isGradientBackground = TRUE; elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality = jQuality; elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = -MinEmHeight; liTotal = ClearTypePerformanceLoopA(hwnd , hdc); liBigTotal += liTotal; liDelta = (ULONG) ((liTotal * 1000) / liFreq); dprintf( " Trsp Grad Time[%d] : %d millisec",LoopCount,liDelta ); } else { SetBkMode( hdc, OPAQUE ); isGradientBackground = FALSE; elfdvW.elfEnumLogfontEx.elfLogFont.lfQuality = jQuality; elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight = -MinEmHeight; liTotal = ClearTypePerformanceLoopW(hwnd , hdc); liBigTotal += liTotal; liDelta = (ULONG) ((liTotal * 1000) / liFreq); dprintf( " Opaque Time[%d] : %d millisec",LoopCount,liDelta ); SetBkMode( hdc, TRANSPARENT ); elfdvW.elfEnumLogfontEx.elfLogFont.lfQuality = jQuality; elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight = -MinEmHeight; liTotal = ClearTypePerformanceLoopW(hwnd , hdc); liBigTotal += liTotal; liDelta = (ULONG) ((liTotal * 1000) / liFreq); dprintf( " Trsp Solid Time[%d] : %d millisec",LoopCount,liDelta ); isGradientBackground = TRUE; elfdvW.elfEnumLogfontEx.elfLogFont.lfQuality = jQuality; elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight = -MinEmHeight; liTotal = ClearTypePerformanceLoopW(hwnd , hdc); liBigTotal += liTotal; liDelta = (ULONG) ((liTotal * 1000) / liFreq); dprintf( " Trsp Grad Time[%d] : %d millisec",LoopCount,liDelta ); } if (!isCharCodingUnicode) { elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = oldHeight; elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality = oldQuality; } else { elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight = oldHeight; elfdvW.elfEnumLogfontEx.elfLogFont.lfQuality = oldQuality; } isGradientBackground = oldIsGradientBackground; liDelta = (ULONG) ((liBigTotal * 1000) / liFreq); dprintf( " TextOutPerformance :" ); dprintf( " TotalTime : %d millisec",liDelta ); dUpdateNow( TRUE ); // DeleteTestIC( hdc ); ReleaseDC(hwnd,hdc); } void ClearTypePerformance ( HWND hwnd ) { DWORD dwOldBatchLimit = GdiSetBatchLimit(1); dprintf( " Monochrome TextOutPerformance :" ); ClearTypePerformanceInternal(hwnd, NONANTIALIASED_QUALITY ); dprintf( " " ); dprintf( " Antialiased TextOutPerformance :" ); ClearTypePerformanceInternal(hwnd, ANTIALIASED_QUALITY ); dprintf( " " ); dprintf( " ClearType TextOutPerformance :" ); ClearTypePerformanceInternal(hwnd, CLEARTYPE_QUALITY ); GdiSetBatchLimit(dwOldBatchLimit); } #endif //***************************************************************************** //************************** P R I N T I T ****************************** //***************************************************************************** void PrintIt( HWND hwnd ) { HDC hdcPrinter; DOCINFO di; INT iOldHeight, iOldWidth; LONG yP, yS, xP, xS; hdcPrinter = CreatePrinterDC(); if( lpfnStartDoc ) { di.cbSize = sizeof(DOCINFO); di.lpszDocName = "FontTest"; di.lpszOutput = NULL; di.lpszDatatype= NULL; di.fwType = 0; dprintf( "Calling StartDoc" ); dprintf( " rc = %d", StartDoc( hdcPrinter, (LPDOCINFO)&di ) ); } else { dprintf( "Sending STARTDOC" ); Escape( hdcPrinter, STARTDOC, lstrlen("FontTest"), "FontTest", NULL ); } if( lpfnStartPage ) { dprintf( "Calling StartPage" ); dprintf( " rc = %d", StartPage( hdcPrinter ) ); } // Height = -(PointSize * Number of pixels per logical inch along the device height)/72. // So the ratio of font heights on two devices is same as the ratio of the pixels // number per logical inch. if (!isCharCodingUnicode) { iOldHeight = elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight; iOldWidth = elfdvA.elfEnumLogfontEx.elfLogFont.lfWidth; } else { iOldHeight = elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight; iOldWidth = elfdvW.elfEnumLogfontEx.elfLogFont.lfWidth; } yP = GetDeviceCaps(hdcPrinter, LOGPIXELSY); yS = GetDeviceCaps(GetDC(hwnd), LOGPIXELSY); xP = GetDeviceCaps(hdcPrinter, LOGPIXELSX); xS = GetDeviceCaps(GetDC(hwnd), LOGPIXELSX); if (!isCharCodingUnicode) { elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = MulDiv(iOldHeight,yP, yS); elfdvA.elfEnumLogfontEx.elfLogFont.lfWidth = MulDiv(iOldWidth,xP, xS); } else { elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight = MulDiv(iOldHeight,yP, yS); elfdvW.elfEnumLogfontEx.elfLogFont.lfWidth = MulDiv(iOldWidth,xP, xS); } SetDCMapMode( hdcPrinter, wMappingMode ); SetTextColor( hdcPrinter, dwRGB ); SetBkMode( hdcPrinter, TRANSPARENT ); SetTextCharacterExtra( hdcPrinter, nCharExtra ); SetTextJustification( hdcPrinter, nBreakExtra, nBreakCount ); DrawDCAxis( NULL, hdcPrinter , TRUE); if( hwndMode == hwndRings ) DrawRings( NULL, hdcPrinter ); else if( hwndMode == hwndString ) DrawString( NULL, hdcPrinter ); else if( hwndMode == hwndWaterfall ) DrawWaterfall( NULL, hdcPrinter ); else if( hwndMode == hwndWhirl ) DrawWhirl( NULL, hdcPrinter ); else if( hwndMode == hwndAnsiSet ) DrawAnsiSet( NULL, hdcPrinter ); else if( hwndMode == hwndGlyphSet ) DrawGlyphSet( NULL, hdcPrinter ); // else if( hwndMode == hwndWidths ) // DrawWidths( NULL, hdcPrinter ); else dprintf( "Can't print current mode" ); if( lpfnEndPage ) { dprintf( "Calling EndPage" ); dprintf( " rc = %d", EndPage( hdcPrinter ) ); } else { dprintf( "Sending NEWFRAME" ); Escape( hdcPrinter, NEWFRAME, 0, NULL, NULL ); } if( lpfnEndDoc ) { dprintf( "Calling EndDoc" ); dprintf( " rc = %d", EndDoc( hdcPrinter ) ); } else { dprintf( "Sending ENDDOC" ); dprintf( " rc = %d", Escape( hdcPrinter, ENDDOC, 0, NULL, NULL ) ); } // Restore the height for the screen dc if (!isCharCodingUnicode) { elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = iOldHeight; elfdvA.elfEnumLogfontEx.elfLogFont.lfWidth = iOldWidth; } else { elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight = iOldHeight; elfdvW.elfEnumLogfontEx.elfLogFont.lfWidth = iOldWidth; } dprintf( "Deleting Printer DC" ); DeleteTestIC( hdcPrinter ); dprintf( "Done printing!" ); } void ChangeCharCoding( HWND hwnd, WPARAM wParam ) { HMENU hMenu; hMenu = GetMenu( hwnd ); CheckMenuItem( hMenu, wCharCoding, MF_UNCHECKED ); CheckMenuItem( hMenu, (UINT)wParam, MF_CHECKED ); wCharCoding = (UINT)wParam; isCharCodingUnicode = (wCharCoding == IDM_CHARCODING_UNICODE)? TRUE : FALSE; if (!isCharCodingUnicode) { dprintf("Switching to ANSI/MBCS"); EnableMenuItem(hMenu, 7, MF_BYPOSITION | MF_ENABLED); EnableMenuItem(hMenu, 8, MF_BYPOSITION | MF_GRAYED); } else { dprintf("Switching to Unicode"); EnableMenuItem(hMenu, 7, MF_BYPOSITION | MF_GRAYED); EnableMenuItem(hMenu, 8, MF_BYPOSITION | MF_ENABLED); } } //***************************************************************************** //******************* C H A N G E M A P M O D E *********************** //***************************************************************************** void ChangeMapMode( HWND hwnd, WPARAM wParam ) { HMENU hMenu; HDC hdc; POINT ptl; hMenu = GetMenu( hwnd ); CheckMenuItem( hMenu, wMappingMode, MF_UNCHECKED ); CheckMenuItem( hMenu, (UINT)wParam, MF_CHECKED ); hdc = GetDC( hwnd ); SetDCMapMode( hdc, wMappingMode ); if (!isCharCodingUnicode) { ptl.x = elfdvA.elfEnumLogfontEx.elfLogFont.lfWidth; ptl.y = elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight; } else { ptl.x = elfdvW.elfEnumLogfontEx.elfLogFont.lfWidth; ptl.y = elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight; } LPtoDP( hdc, &ptl, 1 ); wMappingMode = (UINT)wParam; SetDCMapMode( hdc, wMappingMode ); DPtoLP( hdc, &ptl, 1 ); ptl.x = abs(ptl.x); ptl.y = abs(ptl.y); if (!isCharCodingUnicode) { elfdvA.elfEnumLogfontEx.elfLogFont.lfWidth = (elfdvA.elfEnumLogfontEx.elfLogFont.lfWidth >= 0 ? ptl.x : -ptl.x); // Preserve Sign elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = (elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight >= 0 ? ptl.y : -ptl.y); SyncElfdvAtoW (&elfdvW, &elfdvA); } else { elfdvW.elfEnumLogfontEx.elfLogFont.lfWidth = (elfdvW.elfEnumLogfontEx.elfLogFont.lfWidth >= 0 ? ptl.x : -ptl.x); // Preserve Sign elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight = (elfdvW.elfEnumLogfontEx.elfLogFont.lfHeight >= 0 ? ptl.y : -ptl.y); SyncElfdvWtoA (&elfdvA, &elfdvW); } ReleaseDC( hwnd, hdc ); } //***************************************************************************** //************************ G E T S P A C I N G ************************** //***************************************************************************** LPINT GetSpacing( HDC hdc, LPVOID lpszString ) { LPINT lpdx; LPSTR lpszStringA = lpszString; LPWSTR lpszStringW = lpszString; // only one will be used depending on charcoding int i,j; ABC abc; DWORD cbString; DWORD dwCP = GetCodePage(hdc); //----------------------- Apply Requested Spacing --------------------------- if( wSpacing == IDM_USEDEFAULTSPACING ) return NULL; if( wSpacing == IDM_PDX ) return lpintdx; if( wSpacing == IDM_PDXPDY ) return lpintdx; if (!isCharCodingUnicode) cbString = lstrlenA(lpszStringA); else cbString = lstrlenW(lpszStringW); lpdx = (LPINT)aDx; switch( wSpacing ) { case IDM_USEWIDTHSPACING: dprintf("iwc : ch : Width"); break; case IDM_USEABCSPACING: dprintf("iwc : ch : A : B : C : A+B+C"); break; case IDM_PDX: dprintf("iwc : ch : dx "); break; case IDM_PDXPDY: case IDM_RANDOMPDXPDY: dprintf("iwc : ch : dx : dy "); break; } for( i = 0, j = 0; i < (INT)cbString; i++, j++) { UINT u; BOOL resultOK; BOOL bDBCS = FALSE; int iWidth; int iHeight = 0; if (!isCharCodingUnicode) if (bDBCS = IsDBCSLeadByteEx(dwCP, lpszStringA[i])) { u = (UINT)(BYTE)lpszStringA[i]; u <<= 8; u |= (UINT)(BYTE)lpszStringA[i+1]; } else { u = (UINT)(BYTE)lpszStringA[i]; } else u = (UINT) lpszStringW[i]; switch( wSpacing ) { case IDM_USEWIDTHSPACING: if (!isCharCodingUnicode) GetCharWidthA( hdc, u, u, &iWidth); else GetCharWidthW( hdc, u, u, &iWidth); if (bDBCS) { aDx[i++] = 0; } aDx[i] = iWidth; dprintf("%2ld : 0x%4lx : 0x%lx == %ld", j, u, iWidth, iWidth); break; case IDM_USEABCSPACING: abc.abcA = abc.abcB = abc.abcC = 0; if (!isCharCodingUnicode) resultOK = GetCharABCWidthsA( hdc, u, u, &abc ); else resultOK = GetCharABCWidthsW( hdc, u, u, &abc ); if ( resultOK ) iWidth = abc.abcA + (int)abc.abcB + abc.abcC; else if (!isCharCodingUnicode) GetCharWidthA( hdc, u, u, &iWidth); else GetCharWidthW( hdc, u, u, &iWidth); if (bDBCS) { aDx[i++] = 0; } aDx[i] = iWidth; dprintf("%ld : 0x%lx : 0x%lx : 0x%lx : 0x%lx : 0x%lx ", j, u, abc.abcA, abc.abcB, abc.abcC, iWidth); break; case IDM_RANDOMPDXPDY: if (!isCharCodingUnicode) GetCharWidthA( hdc, u, u, &iWidth); else GetCharWidthW( hdc, u, u, &iWidth); if (wETO & ETO_PDY) iHeight = rand() % 10 - 5; // more or less random number in range (-5,5) if (bDBCS) { aDx[2*i] = 0; aDx[2*i + 1] = 0; i++; } aDx[2*i] = iWidth; aDx[2*i + 1] = iHeight; dprintf("%ld : 0x%lx : 0x%lx : 0x%lx", j, u, iWidth, iHeight); break; } } //--------------------------- Apply Kerning --------------------------------- if( wKerning == IDM_APIKERNING ) { int nPairs; LPKERNINGPAIR lpkp; // dprintf( "GetKerningPairs kerning" ); nPairs = GetKerningPairs( hdc, 0, NULL ); if( nPairs > 0 ) { lpkp = (LPKERNINGPAIR)calloc( 1, nPairs * sizeof(KERNINGPAIR) ); if (!isCharCodingUnicode) GetKerningPairsA( hdc, nPairs, lpkp ); else GetKerningPairsW( hdc, nPairs, lpkp ); for( i = 0; i < (INT)cbString-1; i++ ) { int j; UINT f, s; if (!isCharCodingUnicode) { f = (UINT)(BYTE)lpszStringA[i]; s = (UINT)(BYTE)lpszStringA[i+1]; } else { f = (UINT)lpszStringW[i]; s = (UINT)lpszStringW[i+1]; } for( j = 0; j < nPairs; j++ ) { if( f == lpkp[j].wFirst && s == lpkp[j].wSecond ) { // dprintf( " %c%c == %c%c = %d", lpkp[j].wFirst, lpkp[j].wSecond, lpszString[i], lpszString[i+1], lpkp[j].iKernAmount ); aDx[i] += lpkp[j].iKernAmount; break; } } } if( lpkp ) free( lpkp ); } } else if( wKerning == IDM_ESCAPEKERNING ) { WORD wSize; int wrc; EXTTEXTMETRIC etm; LPKERNPAIR lpkp; // dprintf( "Escape kerning" ); memset( &etm, 0, sizeof(etm) ); wSize = sizeof(etm); // dprintf( "Calling Escape for EXTTEXTMETRIC" ); wrc = ExtEscape( hdc, GETEXTENDEDTEXTMETRICS, 0, NULL, sizeof(EXTTEXTMETRIC), (BYTE *)&etm); // wrc = Escape( hdc, GETEXTENDEDTEXTMETRICS, sizeof(WORD), (LPCSTR)&wSize, &etm ); // dprintf( " wrc = %d", wrc ); if( etm.etmKernPairs > 0 ) { wSize = etm.etmKernPairs * sizeof(KERNPAIR); lpkp = (LPKERNPAIR)calloc( 1, wSize ); // dprintf( "Calling ExtEscape for GETPAIRKERNTABLE" ); wrc = ExtEscape( hdc, GETPAIRKERNTABLE, 0, NULL, wSize, (BYTE *)lpkp ); // dprintf( " wrc = %u", wrc ); for( i = 0; i < (INT)cbString-1; i++ ) { int j; WORD wPair; wPair = (WORD)lpszStringA[i] + ((WORD)lpszStringA[i+1] << 8); for( j = 0; j < etm.etmKernPairs; j++ ) { if( wPair == lpkp[j].wBoth ) { // dprintf( " %c%c == %c%c = %d", lpkp[j].wBoth & 0x00FF, lpkp[j].wBoth >> 8, lpszString[i], lpszString[i+1], lpkp[j].sAmount); aDx[i] += lpkp[j].sAmount; break; } } } if( lpkp ) free( lpkp ); } } return lpdx; } //***************************************************************************** //******************** M Y E X T T E X T O U T ********************** //***************************************************************************** void MyExtTextOut( HDC hdc, int x, int y, DWORD wFlags, LPRECT lpRect, LPVOID lpszString, int cbString, LPINT lpdx ) { int i, iStart; LPSTR lpszStringA = lpszString; LPWSTR lpszStringW = lpszString; DWORD wFlags2; if ( lpRect || (wFlags & ETO_GLYPH_INDEX) || (lpdx && (wFlags & ETO_PDY))) wFlags2 = wFlags; else wFlags2 = 0; if (bGTEExt) doGetTextExtentEx(hdc,x,y,lpszString, cbString); if (bGCP) { doGCP(hdc, x, y, lpszString, cbString); } else { if(lpdx && !wUpdateCP ) { GenExtTextOut( hdc, x, y, wFlags2, lpRect, lpszString, cbString, lpdx ); } else if (wUpdateCP) { SetTextAlign( hdc, wTextAlign | TA_UPDATECP ); MoveToEx( hdc, x, y ,0); iStart = 0; for( i = 1; i < cbString+1; i++ ) { BOOL isTerm; if (!isCharCodingUnicode) isTerm = (lpszStringA[i] == ' ' || lpszStringA[i] == '\0'); else isTerm = (lpszStringW[i] == L' ' || lpszStringW[i] == L'\0'); if( isTerm ) { if (!isCharCodingUnicode) GenExtTextOut( hdc, x, y, wFlags2, lpRect, &lpszStringA[iStart], i-iStart, (lpdx ? &lpdx[iStart] : NULL) ); else GenExtTextOut( hdc, x, y, wFlags2, lpRect, &lpszStringW[iStart], i-iStart, (lpdx ? &lpdx[iStart] : NULL) ); iStart = i; } } } else { GenExtTextOut( hdc, x, y, wFlags2, lpRect, lpszString, cbString, NULL); } } } //***************************************************************************** //********************* S H O W L O G F O N T ************************* //***************************************************************************** void ShowLogFont( void ) { dprintf( " LOGFONT:" ); dprintf( " lfFaceName = '%s'", elfdvA.elfEnumLogfontEx.elfLogFont.lfFaceName ); dprintf( " lfHeight = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight ); dprintf( " lfWidth = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfWidth ); dprintf( " lfEscapement = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfEscapement ); dprintf( " lfOrientation = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfOrientation ); dprintf( " lfWeight = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfWeight ); dprintf( " lfItalic = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfItalic ); dprintf( " lfUnderline = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfUnderline ); dprintf( " lfStrikeOut = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfStrikeOut ); dprintf( " lfCharSet = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfCharSet ); dprintf( " lfOutPrecision = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfOutPrecision ); dprintf( " lfClipPrecision = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfClipPrecision ); dprintf( " lfQuality = %d", elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality ); dprintf( " lfPitchAndFamily = 0x%.2X",elfdvA.elfEnumLogfontEx.elfLogFont.lfPitchAndFamily ); } //***************************************************************************** //*********************** R E S I Z E P R O C *************************** //***************************************************************************** int cxMain, cyMain; int cxMode, cyMode; int cxDebug, cyDebug; void ResizeProc( HWND hwnd ) { HDC hdc; RECT rcl, rclMain; POINT ptl; MSG msg; SetCapture( hwnd ); // Capture All Mouse Messages SetCursor( LoadCursor( NULL, IDC_SIZEWE ) ); hdc = GetDC( hwnd ); GetClientRect( hwndMain, &rclMain ); GetClientRect( hwndMode, &rcl ); rcl.left = rcl.right; rcl.right += cxBorder; DrawFocusRect( hdc, &rcl ); do { while( !PeekMessage( &msg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ) ); if( msg.message == WM_MOUSEMOVE ) { GetCursorPos( &ptl ); ScreenToClient( hwnd, &ptl ); DrawFocusRect( hdc, &rcl ); if( ptl.x < 3*cxBorder ) ptl.x = 3*cxBorder; if( ptl.x > rclMain.right - 3*cxBorder ) ptl.x = rclMain.right - 3*cxBorder; //SetCursorPos( &ptl ); rcl.left = ptl.x; rcl.right = rcl.left + cxBorder; DrawFocusRect( hdc, &rcl ); } } while( msg.message != WM_LBUTTONUP ); DrawFocusRect( hdc, &rcl ); ReleaseDC( hwnd, hdc ); ReleaseCapture(); // Let Go of Mouse MoveWindow( hwndGlyph, 0, 0, rcl.left, rclMain.bottom, FALSE ); MoveWindow( hwndRings, 0, 0, rcl.left, rclMain.bottom, FALSE ); MoveWindow( hwndString, 0, 0, rcl.left, rclMain.bottom, FALSE ); MoveWindow( hwndWaterfall, 0, 0, rcl.left, rclMain.bottom, FALSE ); MoveWindow( hwndWhirl, 0, 0, rcl.left, rclMain.bottom, FALSE ); MoveWindow( hwndAnsiSet, 0, 0, rcl.left, rclMain.bottom, FALSE ); MoveWindow( hwndGlyphSet, 0, 0, rcl.left, rclMain.bottom, FALSE ); MoveWindow( hwndWidths, 0, 0, rcl.left, rclMain.bottom, FALSE ); cxMain = rclMain.right; cyMain = rclMain.bottom; cxMode = rcl.left; cyMode = rclMain.bottom; cxDebug = rclMain.right-rcl.right; cyDebug = rclMain.bottom; InvalidateRect( hwndMode, NULL, TRUE ); InvalidateRect( hwndMain, &rcl, TRUE ); MoveWindow( hwndDebug, rcl.right, 0, rclMain.right-rcl.right, rclMain.bottom, TRUE ); } //***************************************************************************** //*********************** S E L E C T M O D E *************************** //***************************************************************************** void SelectMode( HWND hwnd, WPARAM wParam ) { UINT i; HMENU hMenu; hMenu = GetMenu( hwnd ); // Check if requested mode is disabled, force to String Mode if so if( GetMenuState( hMenu, (UINT)wParam, MF_BYCOMMAND ) & MF_GRAYED ) wParam = IDM_STRINGMODE; wMode = (UINT)wParam; for( i = IDM_GLYPHMODE; i <= IDM_WIDTHSMODE; i++ ) { CheckMenuItem( hMenu, i, MF_UNCHECKED ); } CheckMenuItem( hMenu, wMode, MF_CHECKED ); ShowWindow( hwndGlyph, SW_HIDE ); ShowWindow( hwndRings, SW_HIDE ); ShowWindow( hwndString, SW_HIDE ); ShowWindow( hwndWaterfall, SW_HIDE ); ShowWindow( hwndWhirl, SW_HIDE ); ShowWindow( hwndAnsiSet, SW_HIDE ); ShowWindow( hwndGlyphSet, SW_HIDE ); ShowWindow( hwndWidths, SW_HIDE ); switch( LOWORD(wParam) ) { case IDM_GLYPHMODE: case IDM_BEZIERMODE: case IDM_NATIVEMODE: hwndMode = hwndGlyph; break; case IDM_RINGSMODE: hwndMode = hwndRings; break; case IDM_STRINGMODE: hwndMode = hwndString; break; case IDM_WATERFALLMODE: hwndMode = hwndWaterfall; break; case IDM_WHIRLMODE: hwndMode = hwndWhirl; break; case IDM_ANSISETMODE: hwndMode = hwndAnsiSet; break; case IDM_GLYPHSETMODE: hwndMode = hwndGlyphSet; break; case IDM_WIDTHSMODE: hwndMode = hwndWidths; break; } if( wParam == IDM_GLYPHMODE ) EnableMenuItem( hMenu, IDM_WRITEGLYPH, MF_ENABLED ); else EnableMenuItem( hMenu, IDM_WRITEGLYPH, MF_GRAYED ); ShowWindow( hwndMode, SW_SHOWNORMAL ); } //***************************************************************************** //********** G E T P R I V A T E P R O F I L E D W O R D ************ //***************************************************************************** DWORD GetPrivateProfileDWORD( LPSTR lpszApp, LPSTR lpszKey, DWORD dwDefault, LPSTR lpszINI ) { char szText[16]; wsprintf( szText, "0x%.8lX", dwDefault ); GetPrivateProfileString( lpszApp, lpszKey, szText, szText, sizeof(szText), lpszINI ); return (DWORD)strtoul( szText, NULL, 16 ); } //***************************************************************************** //********* W R I T E P R I V A T E P R O F I L E D W O R D ********* //***************************************************************************** void WritePrivateProfileDWORD( LPSTR lpszApp, LPSTR lpszKey, DWORD dw, LPSTR lpszINI ) { char szText[16]; wsprintf( szText, "0x%.8lX", dw ); WritePrivateProfileString( lpszApp, lpszKey, szText, lpszINI ); } //***************************************************************************** //********** W R I T E P R I V A T E P R O F I L E I N T ************ //***************************************************************************** void WritePrivateProfileInt( LPSTR lpszApp, LPSTR lpszKey, int i, LPSTR lpszINI ) { char szText[16]; wsprintf( szText, "%d", i ); WritePrivateProfileString( lpszApp, lpszKey, szText, lpszINI ); } //***************************************************************************** //****************** X G E T P R O C A D D R E S S ****************** //***************************************************************************** FARPROC XGetProcAddress( LPSTR lpszModule, LPSTR lpszProc ) { return GetProcAddress( GetModuleHandle(lpszModule), lpszProc ); } //***************************************************************************** //******************* V E R S I O N S P E C I F I C S ******************* //***************************************************************************** void VersionSpecifics( HWND hwnd ) { HMENU hMenu; *(FARPROC*)& lpfnCreateScalableFontResource = XGetProcAddress( "GDI32", "CreateScalableFontResourceA" ); *(FARPROC*)& lpfnEnumFontFamilies = XGetProcAddress( "GDI32", "EnumFontFamiliesA" ); *(FARPROC*)& lpfnEnumFontFamiliesEx = XGetProcAddress( "GDI32", "EnumFontFamiliesExA" ); *(FARPROC*)& lpfnGetCharABCWidthsA = XGetProcAddress( "GDI32", "GetCharABCWidthsA" ); *(FARPROC*)& lpfnGetFontData = XGetProcAddress( "GDI32", "GetFontData" ); *(FARPROC*)& lpfnGetGlyphOutlineA = XGetProcAddress( "GDI32", "GetGlyphOutlineA" ); *(FARPROC*)& lpfnGetOutlineTextMetricsA = XGetProcAddress( "GDI32", "GetOutlineTextMetricsA" ); *(FARPROC*)& lpfnGetRasterizerCaps = XGetProcAddress( "GDI32", "GetRasterizerCaps" ); // UNICODE *(FARPROC*)& lpfnGetCharABCWidthsW = XGetProcAddress( "GDI32", "GetCharABCWidthsW" ); *(FARPROC*)& lpfnGetGlyphOutlineW = XGetProcAddress( "GDI32", "GetGlyphOutlineW" ); *(FARPROC*)& lpfnGetOutlineTextMetricsW = XGetProcAddress( "GDI32", "GetOutlineTextMetricsW" ); // END UNICODE *(FARPROC*)& lpfnStartDoc = XGetProcAddress( "GDI32", "StartDocA" ); *(FARPROC*)& lpfnStartPage = XGetProcAddress( "GDI32", "StartPage" ); *(FARPROC*)& lpfnEndPage = XGetProcAddress( "GDI32", "EndPage" ); *(FARPROC*)& lpfnEndDoc = XGetProcAddress( "GDI32", "EndDoc" ); *(FARPROC*)& lpfnAbortDoc = XGetProcAddress( "GDI32", "AbortDoc" ); // dprintf( "lpfnCreateScalableFontResource = 0x%.8lX", lpfnCreateScalableFontResource ); // dprintf( "lpfnEnumFontFamilies = 0x%.8lX", lpfnEnumFontFamilies ); // dprintf( "lpfnGetCharABCWidths = 0x%.8lX", lpfnGetCharABCWidths ); // dprintf( "lpfnGetFontData = 0x%.8lX", lpfnGetFontData ); // dprintf( "lpfnGetGlyphOutline = 0x%.8lX", lpfnGetGlyphOutline ); // dprintf( "lpfnGetOutlineTextMetrics = 0x%.8lX", lpfnGetOutlineTextMetrics ); // dprintf( "lpfnGetRasterizerCaps = 0x%.8lX", lpfnGetRasterizerCaps ); hMenu = GetMenu( hwnd ); if( !lpfnCreateScalableFontResource ) EnableMenuItem( hMenu, IDM_CREATESCALABLEFONTRESOURCE, MF_GRAYED ); if( !lpfnEnumFontFamilies ) EnableMenuItem( hMenu, IDM_ENUMFONTFAMILIES, MF_GRAYED ); if( !lpfnEnumFontFamiliesEx ) EnableMenuItem( hMenu, IDM_ENUMFONTFAMILIESEX, MF_GRAYED ); if( !lpfnGetCharABCWidthsA || !lpfnGetCharABCWidthsA ) EnableMenuItem( hMenu, IDM_GLYPHMODE, MF_GRAYED ); if( !lpfnGetFontData ) EnableMenuItem( hMenu, IDM_GETFONTDATA, MF_GRAYED ); if( !lpfnGetGlyphOutlineA || !lpfnGetGlyphOutlineW ) { EnableMenuItem( hMenu, IDM_GLYPHMODE, MF_GRAYED ); EnableMenuItem( hMenu, IDM_NATIVEMODE, MF_GRAYED ); EnableMenuItem( hMenu, IDM_BEZIERMODE, MF_GRAYED ); } if( !lpfnGetOutlineTextMetricsA || !lpfnGetOutlineTextMetricsW ) EnableMenuItem( hMenu, IDM_GETOUTLINETEXTMETRICS, MF_GRAYED ); if( !lpfnGetRasterizerCaps ) EnableMenuItem( hMenu, IDM_GETRASTERIZERCAPS, MF_GRAYED ); } //***************************************************************************** //************ M M A N I S O T R O P I C D L G P R O C ************** //***************************************************************************** INT_PTR CALLBACK MMAnisotropicDlgProc( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: SetDlgItemInt( hdlg, IDD_XWE, xWE, TRUE ); SetDlgItemInt( hdlg, IDD_YWE, yWE, TRUE ); SetDlgItemInt( hdlg, IDD_XWO, xWO, TRUE ); SetDlgItemInt( hdlg, IDD_YWO, yWO, TRUE ); SetDlgItemInt( hdlg, IDD_XVE, xVE, TRUE ); SetDlgItemInt( hdlg, IDD_YVE, yVE, TRUE ); SetDlgItemInt( hdlg, IDD_XVO, xVO, TRUE ); SetDlgItemInt( hdlg, IDD_YVO, yVO, TRUE ); return TRUE; case WM_COMMAND: switch( LOWORD(wParam) ) { case IDOK: xWE = (int)GetDlgItemInt( hdlg, IDD_XWE, NULL, TRUE ); yWE = (int)GetDlgItemInt( hdlg, IDD_YWE, NULL, TRUE ); xWO = (int)GetDlgItemInt( hdlg, IDD_XWO, NULL, TRUE ); yWO = (int)GetDlgItemInt( hdlg, IDD_YWO, NULL, TRUE ); xVE = (int)GetDlgItemInt( hdlg, IDD_XVE, NULL, TRUE ); yVE = (int)GetDlgItemInt( hdlg, IDD_YVE, NULL, TRUE ); xVO = (int)GetDlgItemInt( hdlg, IDD_XVO, NULL, TRUE ); yVO = (int)GetDlgItemInt( hdlg, IDD_YVO, NULL, TRUE ); EndDialog( hdlg, TRUE ); return TRUE; case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; } break; case WM_CLOSE: EndDialog( hdlg, FALSE ); return TRUE; } return FALSE; } //***************************************************************************** //****************** G E T D L G I T E M D W O R D ****************** //***************************************************************************** DWORD GetDlgItemDWORD( HWND hdlg, int id ) { static char szDWORD[16]; szDWORD[0] = '\0'; GetDlgItemText( hdlg, id, szDWORD, sizeof(szDWORD) ); return (DWORD)atol( szDWORD ); } //***************************************************************************** //****************** G E T D L G I T E M D W O R D ****************** //***************************************************************************** ULONG_PTR GetDlgItemULONG_PTR( HWND hdlg, int id ) { static char szULONG_PTR[32]; szULONG_PTR[0] = '\0'; GetDlgItemText( hdlg, id, szULONG_PTR, sizeof(szULONG_PTR) ); return (ULONG_PTR)atol( szULONG_PTR ); } //***************************************************************************** //****************** S E T D L G I T E M D W O R D ****************** //***************************************************************************** void SetDlgItemDWORD( HWND hdlg, int id, DWORD dw ) { static char szDWORD[16]; szDWORD[0] = '\0'; wsprintf( szDWORD, "%lu", dw ); SetDlgItemText( hdlg, id, szDWORD ); } //***************************************************************************** //******************* S E T D L G I T E M L O N G ******************* //***************************************************************************** void SetDlgItemLONG( HWND hdlg, int id, LONG l ) { static char szLONG[16]; szLONG[0] = '\0'; wsprintf( szLONG, "%ld", l ); SetDlgItemText( hdlg, id, szLONG ); } //***************************************************************************** //****************** D O G E T F O N T D A T A ********************** //***************************************************************************** #define BUFFER_SIZE 4096 typedef BYTE *HPBYTE; void DoGetFontData( char szTable[], DWORD dwOffset, DWORD cbData, DWORD dwSize, PSTR pszFile ) { HDC hdc; HFONT hFont, hFontOld; HANDLE hData; HPBYTE hpData; DWORD dwrc; DWORD dwTable; hData = NULL; hpData = NULL; hdc = CreateTestIC(); hFont = CreateFontIndirectWrapperA( &elfdvA ); hFontOld = SelectObject( hdc, hFont ); if( dwSize ) { hData = GlobalAlloc( GHND, dwSize ); hpData = (HPBYTE)GlobalLock( hData ); } // dwTable = ( ((DWORD)(szTable[0]) << 0) + // ((DWORD)(szTable[1]) << 8) + // ((DWORD)(szTable[2]) << 16) + // ((DWORD)(szTable[3]) << 24) ); dwTable = *(LPDWORD)szTable; if(!strcmp(szTable,"0")) { // get the whole file dwTable = 0; } dprintf( "Calling GetFontData" ); dprintf( " dwTable = 0x%.8lX (%s)", dwTable, szTable ); dprintf( " dwOffset = %lu", dwOffset ); dprintf( " lpData = 0x%.8lX", hpData ); dprintf( " cbData = %ld", cbData ); dprintf( " hBuf = 0x%.4X", hData ); dprintf( " dwBuf = %ld", dwSize ); dwrc = lpfnGetFontData( hdc, dwTable, dwOffset, hpData, cbData ); dprintf( " dwrc = %ld", dwrc ); SelectObject( hdc, hFontOld ); DeleteObject( hFont ); DeleteTestIC( hdc ); if( dwrc && lstrlen(pszFile) > 0 ) { int fh; WORD wCount; DWORD dw; LPBYTE lpb; lpb = (LPBYTE)calloc( 1, BUFFER_SIZE ); fh = _lcreat( pszFile, 0 ); wCount = 0; for( dw = 0; dw < dwrc; dw++ ) { lpb[wCount++] = hpData[dw]; if( wCount == BUFFER_SIZE ) { dprintf( " Writing %u bytes", wCount ); _lwrite( fh, lpb, wCount ); wCount = 0; } } if( wCount > 0 ) { dprintf( " Writing %u bytes", wCount ); _lwrite( fh, lpb, wCount ); } _lclose( fh ); free( lpb ); } if( hData ) { GlobalUnlock( hData ); GlobalFree( hData ); } } //***************************************************************************** //************* G E T F O N T D A T A D L G P R O C *************** //***************************************************************************** INT_PTR CALLBACK GetFontDataDlgProc( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam ) { static DWORD dwOffset; static DWORD dwChunk; static DWORD dwSize; static char szTable[5]; static char szFile[260]; switch( msg ) { case WM_INITDIALOG: SetDlgItemText( hdlg, IDD_DWTABLE, szTable ); SendDlgItemMessage( hdlg, IDD_DWTABLE, EM_LIMITTEXT, sizeof(szTable)-1, 0 ); SetDlgItemDWORD( hdlg, IDD_DWOFFSET, dwOffset ); SetDlgItemLONG( hdlg, IDD_DWCHUNK, (LONG)dwChunk ); SetDlgItemDWORD( hdlg, IDD_DWSIZE, dwSize ); SetDlgItemText( hdlg, IDD_LPSZFILE, szFile ); SendDlgItemMessage( hdlg, IDD_LPSZFILE, EM_LIMITTEXT, sizeof(szFile)-1, 0 ); return TRUE; case WM_COMMAND: switch( LOWORD(wParam) ) { case IDOK: szTable[0] = '\0'; szTable[1] = '\0'; szTable[2] = '\0'; szTable[3] = '\0'; szTable[4] = '\0'; GetDlgItemText( hdlg, IDD_DWTABLE, szTable, sizeof(szTable) ); dwOffset = GetDlgItemDWORD( hdlg, IDD_DWOFFSET ); dwChunk = GetDlgItemDWORD( hdlg, IDD_DWCHUNK ); dwSize = GetDlgItemDWORD( hdlg, IDD_DWSIZE ); szFile[0] = 0; GetDlgItemText( hdlg, IDD_LPSZFILE, szFile, sizeof(szFile) ); DoGetFontData( szTable, dwOffset, dwChunk, dwSize, szFile ); EndDialog( hdlg, TRUE ); return TRUE; case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; } break; case WM_CLOSE: EndDialog( hdlg, FALSE ); return TRUE; } return FALSE; } //***************************************************************************** //****** C R E A T E S C A L A B L E F O N T D L G P R O C ****** //***************************************************************************** INT_PTR CALLBACK CreateScalableFontDlgProc( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam ) { int rc; LPSTR lpszResourceFile, lpszFontFile, lpszCurrentPath; static UINT fHidden; static DWORD temp; static char szResourceFile[260]; static char szFontFile[260]; static char szCurrentPath[260]; switch( msg ) { case WM_INITDIALOG: SetDlgItemInt( hdlg, IDD_FHIDDEN, fHidden, FALSE ); SetDlgItemText( hdlg, IDD_LPSZRESOURCEFILE, szResourceFile ); SetDlgItemText( hdlg, IDD_LPSZFONTFILE, szFontFile ); SetDlgItemText( hdlg, IDD_LPSZCURRENTPATH, szCurrentPath ); SendDlgItemMessage( hdlg, IDD_LPSZRESOURCEFILE, EM_LIMITTEXT, sizeof(szResourceFile), 0); SendDlgItemMessage( hdlg, IDD_LPSZFONTFILE, EM_LIMITTEXT, sizeof(szFontFile), 0); SendDlgItemMessage( hdlg, IDD_LPSZCURRENTPATH, EM_LIMITTEXT, sizeof(szCurrentPath), 0); return TRUE; case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: szResourceFile[0] = 0; szFontFile[0] = 0; szCurrentPath[0] = 0; // need ia64 cleanup : temp = (UINT)GetDlgItemInt( hdlg, IDD_FHIDDEN, NULL, FALSE ); fHidden = (UINT)temp; GetDlgItemText( hdlg, IDD_LPSZRESOURCEFILE, szResourceFile, sizeof(szResourceFile) ); GetDlgItemText( hdlg, IDD_LPSZFONTFILE, szFontFile, sizeof(szFontFile) ); GetDlgItemText( hdlg, IDD_LPSZCURRENTPATH, szCurrentPath, sizeof(szCurrentPath) ); dprintf( "Calling CreateScalableFontResource" ); lpszResourceFile = (lstrlen(szResourceFile) ? szResourceFile : NULL); lpszFontFile = (lstrlen(szFontFile) ? szFontFile : NULL); lpszCurrentPath = (lstrlen(szCurrentPath) ? szCurrentPath : NULL); rc = lpfnCreateScalableFontResource( fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath ); dprintf( " rc = %d", rc ); EndDialog( hdlg, TRUE ); return TRUE; case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; } break; case WM_CLOSE: EndDialog( hdlg, FALSE ); return TRUE; } return FALSE; } #ifdef USERGETWVTPERF typedef LONG (*LPWINVERIFYTRUST) (HWND, GUID *, LPVOID); //********************************************************************************** //********** W V T F O N T E V A L U A T I O N D L G P R O C ********** //********************************************************************************** ULONG AuthenticFontSignature_MemPtr(BYTE *pbFile, ULONG cbFile, GUID *pguid, BOOL fFileCheck) { GUID gV2 = WINTRUST_ACTION_GENERIC_VERIFY_V2; WINTRUST_DATA sWTD; WINTRUST_BLOB_INFO sWTBI; HANDLE hDll; LPWINVERIFYTRUST lpWinVerifyTrust = NULL; ULONG fl; memset(&sWTD, 0x00, sizeof(WINTRUST_DATA)); memset(&sWTBI, 0x00, sizeof(WINTRUST_BLOB_INFO)); sWTD.cbStruct = sizeof(WINTRUST_DATA); sWTD.dwUIChoice = WTD_UI_NONE; sWTD.dwUnionChoice = WTD_CHOICE_BLOB; sWTD.pBlob = &sWTBI; sWTBI.cbStruct = sizeof(WINTRUST_BLOB_INFO); sWTBI.gSubject = *pguid; sWTBI.cbMemObject = cbFile; sWTBI.pbMemObject = pbFile; // hDll = LoadLibrary("wintrust"); fl = 0; // if(hDll) // { // lpWinVerifyTrust = (LPWINVERIFYTRUST) GetProcAddress(hDll, "WinVerifyTrustEx"); // if(lpWinVerifyTrust) // { if (WinVerifyTrust((HWND) 10, &gV2, &sWTD) == ERROR_SUCCESS) { // dprintf((" We have succeed to do it\n")); fl = TRUE; } else { // dprintf((" Oh, no it failed\n")); } // } // FreeLibrary(hDll); // } return fl; } ULONG AuthenticFontSignature_FileHandle(HANDLE hFile, GUID *pguid, BOOL fFileCheck) { GUID gV2 = WINTRUST_ACTION_GENERIC_VERIFY_V2; WINTRUST_DATA sWTD; WINTRUST_FILE_INFO sWTFI; HANDLE hDll; LPWINVERIFYTRUST lpWinVerifyTrust = NULL; ULONG fl; memset(&sWTD, 0x00, sizeof(WINTRUST_DATA)); memset(&sWTFI, 0x00, sizeof(WINTRUST_FILE_INFO)); sWTD.cbStruct = sizeof(WINTRUST_DATA); sWTD.dwUIChoice = WTD_UI_NONE; sWTD.dwUnionChoice = WTD_CHOICE_FILE; sWTD.pFile = &sWTFI; sWTFI.cbStruct = sizeof(WINTRUST_FILE_INFO); sWTFI.hFile = hFile; sWTFI.pcwszFilePath = NULL; sWTFI.pgKnownSubject = pguid; // hDll = LoadLibrary("wintrust"); fl = 0; // if(hDll) // { // lpWinVerifyTrust = (LPWINVERIFYTRUST) GetProcAddress(hDll, "WinVerifyTrustEx"); // if(lpWinVerifyTrust) // { if (WinVerifyTrust((HWND) 10, &gV2, &sWTD) == ERROR_SUCCESS) { // dprintf((" We have succeed to do it\n")); fl = TRUE; } else { // dprintf((" Oh, no it failed\n")); } // } // FreeLibrary(hDll); // } return fl; } ULONG AuthenticFontSignature_FilePath(LPWSTR pwszPathFileName, GUID *pguid, BOOL fFileCheck) { GUID gV2 = WINTRUST_ACTION_GENERIC_VERIFY_V2; WINTRUST_DATA sWTD; WINTRUST_FILE_INFO sWTFI; HANDLE hDll; LPWINVERIFYTRUST lpWinVerifyTrust = NULL; ULONG fl; memset(&sWTD, 0x00, sizeof(WINTRUST_DATA)); memset(&sWTFI, 0x00, sizeof(WINTRUST_FILE_INFO)); sWTD.cbStruct = sizeof(WINTRUST_DATA); sWTD.dwUIChoice = WTD_UI_NONE; sWTD.dwUnionChoice = WTD_CHOICE_FILE; sWTD.pFile = &sWTFI; sWTFI.cbStruct = sizeof(WINTRUST_FILE_INFO); sWTFI.hFile = INVALID_HANDLE_VALUE; sWTFI.pcwszFilePath = pwszPathFileName; sWTFI.pgKnownSubject = pguid; // hDll = LoadLibrary("wintrust"); fl = 0; // if(hDll) // { // lpWinVerifyTrust = (LPWINVERIFYTRUST) GetProcAddress(hDll, "WinVerifyTrustEx"); // if(lpWinVerifyTrust) // { if (WinVerifyTrust((HWND) 10, &gV2, &sWTD) == ERROR_SUCCESS) { // dprintf((" We have succeed to do it\n")); fl = TRUE; } else { // dprintf((" Oh, no it failed\n")); } // } // FreeLibrary(hDll); // } return fl; } ULONG HashFile_MemPtr (HCRYPTPROV hProv, BYTE *pbFile, ULONG cbFile) { HCRYPTHASH hHash; BYTE *pbHash = NULL; ULONG cbHash = 16; ALG_ID alg_id = CALG_MD5; // Set hHashTopLevel to be the hash object. if (!CryptCreateHash(hProv, alg_id, 0, 0, &hHash)) { dprintf ("Error during CryptCreateHash.\n"); goto done; } // Allocate memory for the hash value. if ((pbHash = (BYTE *) malloc (cbHash)) == NULL) { dprintf ("Error in malloc.\n"); goto done; } //// Pump the bytes of the new file into the hash function if (!CryptHashData (hHash, pbFile, cbFile, 0)) { dprintf ("Error during CryptHashData.\n"); goto done; } //// Compute the top-level hash value, and place the resulting //// hash value into pbHashTopLevel. if (!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &cbHash, 0)) { dprintf ("Error during CryptGetHashParam (hash value)\n"); goto done; } done: if (pbHash) { free (pbHash); } return TRUE; } // WVT Performance tests #define PERF_CRYPTHASHDATA_ONLY 0 #define PERF_WVT_ONLY 1 #define PERF_EVERYTHING 2 INT_PTR CALLBACK GetWVTPerfDlgProc( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam ) { int rc = 0; ULONG i; LPSTR lpszFile = NULL; WCHAR wPathFileName[260]; BOOL fFileHandle; BOOL fFilePath; HANDLE hFile = NULL; HANDLE hMapFile = NULL; BYTE *pbFile = NULL; ULONG cbFile = 0; BOOL fFileCheck; GUID gFont = CRYPT_SUBJTYPE_FONT_IMAGE; GUID guid; GUID *ptheguid = NULL; HCRYPTPROV hProv = 0; HMODULE hdll = NULL; ULONG ulPerfTest; ULONG ulIterations; _int64 liStart; _int64 liNow; _int64 liFreq; ULONG liDelta; static char szFile[260]; switch( msg ) { case WM_INITDIALOG: SetDlgItemText( hdlg, IDD_LPSZFILE, szFile ); SendDlgItemMessage( hdlg, IDD_LPSZFILE, EM_LIMITTEXT, sizeof(szFile), 0); // turn on the Memory Pointer radio button CheckRadioButton(hdlg, IDC_WVT_FILE_PATH, IDC_WVT_MEM_PTR, IDC_WVT_MEM_PTR); // turn on the Memory Pointer radio button CheckRadioButton(hdlg, IDC_CRYPTHASHDATA_ONLY, IDC_EVERYTHING, IDC_EVERYTHING); // turn on the Font Hint radio button CheckDlgButton(hdlg, IDC_FONT_HINT, 1); // default number of iterations is 1 SetDlgItemInt ( hdlg, IDC_WVT_ITERATIONS, 1, TRUE); gTime = 0; SetTimer(hdlg, 0, 1000, (TIMERPROC) Mytimer); return TRUE; case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: szFile[0] = 0; GetDlgItemText( hdlg, IDD_LPSZFILE, szFile, sizeof(szFile) ); dprintf( "Evaluate TT in WVT's performance" ); lpszFile = (lstrlen(szFile) ? szFile : NULL); dprintf ("lpszFile: '%s'", lpszFile); MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, lpszFile, -1, wPathFileName, 260); fFileHandle = (IsDlgButtonChecked(hdlg, IDC_WVT_FILE_HANDLE) ? TRUE : FALSE); fFilePath = (IsDlgButtonChecked(hdlg, IDC_WVT_FILE_PATH) ? TRUE : FALSE); if (IsDlgButtonChecked (hdlg, IDC_CRYPTHASHDATA_ONLY)) { ulPerfTest = PERF_CRYPTHASHDATA_ONLY; } else if (IsDlgButtonChecked (hdlg, IDC_WVT_ONLY)) { ulPerfTest = PERF_WVT_ONLY; } else if (IsDlgButtonChecked (hdlg, IDC_EVERYTHING)) { ulPerfTest = PERF_EVERYTHING; } if (IsDlgButtonChecked(hdlg, IDC_FONT_HINT)) { guid = gFont; fFileCheck = FALSE; } else fFileCheck = TRUE; ulIterations = GetDlgItemInt(hdlg, IDC_WVT_ITERATIONS, NULL, TRUE); dprintf ("fFileHandle: %d", fFileHandle); dprintf ("fFilePath : %d", fFilePath); dprintf ("fFileCheck: %d", fFileCheck); dprintf ("ulPerfTest: %d", ulPerfTest); dprintf ("wPathFileName: '%S'", wPathFileName); dprintf ("ulIterations: %d", ulIterations); if ((hdll = LoadLibraryA ("mssipotf")) == NULL) { dprintf ("LoadLibraryA(mssipotf) failed."); } if (!fFilePath && !fFileHandle && (ulPerfTest != PERF_CRYPTHASHDATA_ONLY)) { if (fFileCheck) { dprintf ("Bad combination of options."); break; } dprintf ("Mapping file and verifying ..."); if (ulPerfTest == PERF_EVERYTHING) { QueryPerformanceCounter((LARGE_INTEGER *) &liStart); } for(i = 0; i < ulIterations; i++) { // convert file path name into a file handle if ((hFile = CreateFile (lpszFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) { dprintf ("Error in CreateFile."); goto done; } // map the file into memory before calling WVT if ((hMapFile = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) { dprintf ("Error in CreateFileMapping."); goto done; } if ((pbFile = (BYTE *) MapViewOfFile (hMapFile, FILE_MAP_READ, 0, 0, 0)) == NULL) { dprintf ("Error in MapViewOfFile."); goto done; } if ((cbFile = GetFileSize (hFile, NULL)) == 0xFFFFFFFF) { dprintf ("Error in GetFileSize."); goto done; } if (ulPerfTest == PERF_WVT_ONLY) { QueryPerformanceCounter((LARGE_INTEGER *) &liStart); } rc = AuthenticFontSignature_MemPtr (pbFile, cbFile, &guid, fFileCheck); if (rc == 0) { dprintf( " AuthenticFontSignature_MemPtr failed"); dprintf( " rc = %d", rc ); } if (ulPerfTest == PERF_WVT_ONLY) { QueryPerformanceCounter((LARGE_INTEGER *) &liNow); QueryPerformanceFrequency((LARGE_INTEGER *) &liFreq); } // unmap the file if (hMapFile) { // dprintf ("Unmapping file (1) ..."); CloseHandle (hMapFile); } if (pbFile) { // dprintf ("Unmapping file (2) ..."); UnmapViewOfFile (pbFile); } if (hFile) { // dprintf ("Unmapping file (3) ..."); CloseHandle (hFile); } } if (ulPerfTest == PERF_EVERYTHING) { QueryPerformanceCounter((LARGE_INTEGER *) &liNow); QueryPerformanceFrequency((LARGE_INTEGER *) &liFreq); } } else if (fFileHandle) { dprintf ("Creating and using file handle to verify ..."); if (fFileCheck) { ptheguid = NULL; } else { ptheguid = &guid; } if (ulPerfTest == PERF_EVERYTHING) { QueryPerformanceCounter((LARGE_INTEGER *) &liStart); } for(i = 0; i < ulIterations; i++) { // convert file path name into a file handle if ((hFile = CreateFile (lpszFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) { dprintf ("Error in CreateFile."); goto done; } if (ulPerfTest == PERF_WVT_ONLY) { QueryPerformanceCounter((LARGE_INTEGER *) &liStart); } rc = AuthenticFontSignature_FileHandle (hFile, ptheguid, fFileCheck); if (rc == 0) { dprintf( " AuthenticFontSignature_FileHandle failed"); dprintf( " rc = %d", rc ); } if (ulPerfTest == PERF_WVT_ONLY) { QueryPerformanceCounter((LARGE_INTEGER *) &liNow); QueryPerformanceFrequency((LARGE_INTEGER *) &liFreq); } if (hFile) { CloseHandle (hFile); } } if (ulPerfTest == PERF_EVERYTHING) { QueryPerformanceCounter((LARGE_INTEGER *) &liNow); QueryPerformanceFrequency((LARGE_INTEGER *) &liFreq); } } else if (fFilePath) { dprintf ("Using file pathname to verify ..."); if (fFileCheck) { ptheguid = NULL; } else { ptheguid = &guid; } if ((ulPerfTest == PERF_EVERYTHING) || (ulPerfTest == PERF_WVT_ONLY)) { QueryPerformanceCounter((LARGE_INTEGER *) &liStart); } for(i = 0; i < ulIterations; i++) rc = AuthenticFontSignature_FilePath (wPathFileName, ptheguid, fFileCheck); if (rc == 0) { dprintf( " AuthenticFontSignature_FilePath failed"); dprintf( " rc = %d", rc ); } if ((ulPerfTest == PERF_EVERYTHING) || (ulPerfTest == PERF_WVT_ONLY)) { QueryPerformanceCounter((LARGE_INTEGER *) &liNow); QueryPerformanceFrequency((LARGE_INTEGER *) &liFreq); } } else { // ASSERT: ulPerfTest == 0 dprintf ("Performing CryptHashData only on the file ...\n"); // convert file path name into a file handle if ((hFile = CreateFile (lpszFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) { printf ("Error in CreateFile.\n"); goto done; } // map the file into memory before calling WVT if ((hMapFile = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) { printf ("Error in CreateFileMapping.\n"); goto done; } if ((pbFile = (BYTE *) MapViewOfFile (hMapFile, FILE_MAP_READ, 0, 0, 0)) == NULL) { printf ("Error in MapViewOfFile.\n"); goto done; } if ((cbFile = GetFileSize (hFile, NULL)) == 0xFFFFFFFF) { printf ("Error in GetFileSize.\n"); goto done; } #if DBG dprintf ("pbFile = %d\n", pbFile); dprintf ("cbFile = %d\n", cbFile); #endif // Set hProv to point to a cryptographic context of the default CSP. if (!CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { printf ("Error during CryptAcquireContext. "); printf ("last error = %x.\n", GetLastError ()); goto done; } QueryPerformanceCounter((LARGE_INTEGER *) &liStart); for(i = 0; i < ulIterations; i++) { rc = HashFile_MemPtr (hProv, pbFile, cbFile); if (rc == 0) { dprintf( " HashFile_MemPtr failed"); dprintf( " rc = %d", rc ); } } QueryPerformanceCounter((LARGE_INTEGER *) &liNow); QueryPerformanceFrequency((LARGE_INTEGER *) &liFreq); if (hProv) { CryptReleaseContext(hProv, 0); } // unmap the file if (hMapFile) { #if DBG dprintf ("Unmapping file (1) ...\n"); #endif CloseHandle (hMapFile); } if (pbFile) { #if DBG dprintf ("Unmapping file (2) ...\n"); #endif UnmapViewOfFile (pbFile); } if (hFile) { #if DBG dprintf ("Unmapping file (3) ...\n"); #endif CloseHandle (hFile); } } done: dprintf( " rc = %d", rc ); if( rc ) { liNow = liNow - liStart; liDelta = (ULONG) ((liNow * 1000) / liFreq); dprintf( " Time is %d milliseconds", liDelta ); } else { dprintf((" Failed to get WVT performance")); } if (hdll) { FreeLibrary (hdll); } EndDialog( hdlg, TRUE ); return TRUE; case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; case IDC_WVT_FILE_PATH: case IDC_WVT_FILE_HANDLE: case IDC_WVT_MEM_PTR: CheckRadioButton (hdlg, IDC_WVT_FILE_PATH, IDC_WVT_MEM_PTR, LOWORD(wParam)); return TRUE; case IDC_CRYPTHASHDATA_ONLY: case IDC_WVT_ONLY: case IDC_EVERYTHING: CheckRadioButton (hdlg, IDC_CRYPTHASHDATA_ONLY, IDC_EVERYTHING, LOWORD(wParam)); return TRUE; } break; case WM_CLOSE: KillTimer(hdlg, 0); EndDialog( hdlg, FALSE ); return TRUE; } return FALSE; } #endif //***************************************************************************** //********** A D D F O N T R E S O U R C E D L G P R O C ********** //***************************************************************************** INT_PTR CALLBACK AddFontResourceDlgProc( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam ) { int rc; LPSTR lpszFile; static char szFile[260]; switch( msg ) { case WM_INITDIALOG: SetDlgItemText( hdlg, IDD_LPSZFILE, szFile ); SendDlgItemMessage( hdlg, IDD_LPSZFILE, EM_LIMITTEXT, sizeof(szFile), 0); return TRUE; case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: szFile[0] = 0; GetDlgItemText( hdlg, IDD_LPSZFILE, szFile, sizeof(szFile) ); dprintf( "Calling AddFontResource" ); lpszFile = (lstrlen(szFile) ? szFile : NULL); rc = AddFontResource( lpszFile ); dprintf( " rc = %d", rc ); EndDialog( hdlg, TRUE ); return TRUE; case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; } break; case WM_CLOSE: EndDialog( hdlg, FALSE ); return TRUE; } return FALSE; } //***************************************************************************** //********** A D D F O N T R E S O U R C E E X D L G P R O C ****** //***************************************************************************** INT_PTR CALLBACK AddFontResourceExDlgProc( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam ) { #ifdef GI_API int rc; LPSTR lpszFile; DWORD fl; INT_PTR result; static char szFile[260]; DESIGNVECTOR dvMMInfo; switch( msg ) { case WM_INITDIALOG: SetDlgItemText( hdlg, IDD_LPSZFILE, szFile ); SendDlgItemMessage( hdlg, IDD_LPSZFILE, EM_LIMITTEXT, sizeof(szFile), 0); return TRUE; case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: szFile[0] = 0; // read the check buttons and the font filename GetDlgItemText( hdlg, IDD_LPSZFILE, szFile, sizeof(szFile) ); fl = IsDlgButtonChecked( hdlg, IDD_PRIVATE) ? FR_PRIVATE : 0; fl |= IsDlgButtonChecked( hdlg, IDD_NOTENUM) ? FR_NOT_ENUM : 0; // read the axes information if (!fReadDesignVector(hdlg, (LPDESIGNVECTOR) &dvMMInfo)) { ShowDialogBox( AddFontResourceExDlgProc, IDB_ADDFONTRESOURCEEX, NULL); return FALSE; } dprintf( "Calling AddFontResourceEx" ); lpszFile = (lstrlen(szFile) ? szFile : NULL); rc = AddFontResourceEx( lpszFile, fl, NULL); dprintf( " rc = %d", rc); EndDialog( hdlg, TRUE ); return TRUE; case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; } break; case WM_CLOSE: EndDialog( hdlg, FALSE ); return TRUE; } #endif return FALSE; } //***************************************************************************** //****** R E M O V E F O N T R E S O U R C E D L G P R O C ******** //***************************************************************************** INT_PTR CALLBACK RemoveFontResourceDlgProc( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam ) { int rc; LPSTR lpszFile; static char szFile[260]; switch( msg ) { case WM_INITDIALOG: SetDlgItemText( hdlg, IDD_LPSZFILE, szFile ); SendDlgItemMessage( hdlg, IDD_LPSZFILE, EM_LIMITTEXT, sizeof(szFile), 0); return TRUE; case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: szFile[0] = 0; GetDlgItemText( hdlg, IDD_LPSZFILE, szFile, sizeof(szFile) ); dprintf( "Calling RemoveFontResource" ); lpszFile = (lstrlen(szFile) ? szFile : NULL); rc = RemoveFontResource( lpszFile ); dprintf( " rc = %d", rc ); EndDialog( hdlg, TRUE ); return TRUE; case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; } break; case WM_CLOSE: EndDialog( hdlg, FALSE ); return TRUE; } return FALSE; } //***************************************************************************** //****** R E M O V E F O N T R E S O U R C E E X D L G P R O C **** //***************************************************************************** INT_PTR CALLBACK RemoveFontResourceExDlgProc( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam ) { #ifdef GI_API int rc; LPSTR lpszFile; DWORD fl; static char szFile[260]; DESIGNVECTOR dvMMInfo; switch( msg ) { case WM_INITDIALOG: SetDlgItemText( hdlg, IDD_LPSZFILE, szFile ); SendDlgItemMessage( hdlg, IDD_LPSZFILE, EM_LIMITTEXT, sizeof(szFile), 0); return TRUE; case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: szFile[0] = 0; // read filename and the check buttons. GetDlgItemText( hdlg, IDD_LPSZFILE, szFile, sizeof(szFile) ); fl = IsDlgButtonChecked( hdlg, IDD_PRIVATE) ? FR_PRIVATE : 0; fl |= IsDlgButtonChecked( hdlg, IDD_NOTENUM) ? FR_NOT_ENUM : 0; // read the axes information if (!fReadDesignVector(hdlg, (LPDESIGNVECTOR) &dvMMInfo)) { ShowDialogBox( RemoveFontResourceExDlgProc, IDB_REMOVEFONTRESOURCEEX, NULL); return FALSE; } dprintf( "Calling RemoveFontResourceEx" ); lpszFile = (lstrlen(szFile) ? szFile : NULL); rc = RemoveFontResourceEx( lpszFile, fl, NULL); dprintf( " rc = %d", rc ); EndDialog( hdlg, TRUE ); return TRUE; case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; } break; case WM_CLOSE: EndDialog( hdlg, FALSE ); return TRUE; } #endif return FALSE; } //********************************************************************** //**** ADD F O N T MEM R E S O U R C E E X DLG P R O C ******* //********************************************************************** INT_PTR CALLBACK AddFontMemResourceExDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { #ifdef GI_API HANDLE hMMFont; ULONG cFonts; LPSTR lpszFile; HANDLE hFile, hFileMapping; DWORD lastError; static char szFile[260]; DESIGNVECTOR dvMMInfo; switch( msg ) { case WM_INITDIALOG: SetDlgItemText( hdlg, IDD_LPSZFILE, szFile ); SendDlgItemMessage( hdlg, IDD_LPSZFILE, EM_LIMITTEXT, sizeof(szFile), 0); return TRUE; case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: szFile[0] = 0; // read the check buttons and the font filename GetDlgItemText( hdlg, IDD_LPSZFILE, szFile, sizeof(szFile) ); dprintf( "Calling AddFontMemResourceEx" ); lpszFile = (lstrlen(szFile) ? szFile : NULL); // read the axes information if (!fReadDesignVector(hdlg, (LPDESIGNVECTOR) &dvMMInfo)) { ShowDialogBox( AddFontResourceExDlgProc, IDB_ADDFONTRESOURCEEX, NULL); return FALSE; } if (lpszFile) { hFile = CreateFile(lpszFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile != INVALID_HANDLE_VALUE) { DWORD cjSize; PVOID pFontFile; cjSize = GetFileSize(hFile, NULL); if (cjSize == -1) { dprintf("GetFileSize() failed\n"); return TRUE; } hFileMapping = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, "mappingobject"); if (hFileMapping) { pFontFile = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); if(pFontFile) { hMMFont = AddFontMemResourceEx(pFontFile, cjSize, NULL, &cFonts); dprintf("hMMFont = %ld cFonts = %ld\n", hMMFont, cFonts); UnmapViewOfFile(pFontFile); } else { dprintf("MapViewOfFile() failed\n"); } CloseHandle(hFileMapping); } else { dprintf("CreateFileMapping() failed\n"); } CloseHandle(hFile); } } EndDialog( hdlg, TRUE ); if (hMMFont) return TRUE; else return FALSE; case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; } break; case WM_CLOSE: EndDialog( hdlg, FALSE ); return TRUE; } #endif return FALSE; } //******************************************************************** //**** REMOVE F O N T MEM R E S O U R C E E X P R O C ****** //******************************************************************** INT_PTR CALLBACK RemoveFontMemResourceExDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { #ifdef GI_API HANDLE hMMFont; BOOL bRet; switch( msg ) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch( LOWORD(wParam) ) { case IDOK: dprintf("Calling RemoveFontMemResourceEx()\n"); hMMFont = (HANDLE)GetDlgItemULONG_PTR(hdlg, IDD_HMMFONT ); bRet = RemoveFontMemResourceEx(hMMFont); dprintf("bRet = %d\n", bRet); EndDialog( hdlg, TRUE ); return TRUE; case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; } break; case WM_CLOSE: EndDialog( hdlg, FALSE ); return TRUE; } #endif // GI_API return FALSE; } //***************************************************************************** //********************* U S E S T O C K F O N T *********************** //***************************************************************************** void UseStockFont( WORD w ) { int nIndex, nCount; HFONT hFont; switch( w ) { case IDM_ANSIFIXEDFONT: nIndex = ANSI_FIXED_FONT; break; case IDM_ANSIVARFONT: nIndex = ANSI_VAR_FONT; break; case IDM_DEVICEDEFAULTFONT: nIndex = DEVICE_DEFAULT_FONT; break; case IDM_OEMFIXEDFONT: nIndex = OEM_FIXED_FONT; break; case IDM_SYSTEMFONT: nIndex = SYSTEM_FONT; break; case IDM_SYSTEMFIXEDFONT: nIndex = SYSTEM_FIXED_FONT; break; case IDM_DEFAULTGUIFONT: nIndex = DEFAULT_GUI_FONT; break; default: nIndex = SYSTEM_FIXED_FONT; break; } dprintf( "GetStockObject( %d )", nIndex ); hFont = GetStockObject(nIndex); dprintf( " hFont = 0x%.4X", hFont ); // dprintf( "GetObject for size" ); // nCount = GetObject( hFont, 0, NULL ); // dprintf( " nCount = %d", nCount ); dprintf( "GetObject" ); nCount = GetObject( hFont, sizeof(elfdvA.elfEnumLogfontEx.elfLogFont), (LPSTR)&elfdvA.elfEnumLogfontEx.elfLogFont ); dprintf( " nCount = %d", nCount ); } //***************************************************************************** //********************* M A I N W N D P R O C ************************* //***************************************************************************** char szINIFile[128]; LRESULT CALLBACK MainWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { HMENU hMenu; UINT wtMode; int i; static OPENFILENAME ofn; static char szNewLog[256]; static LPSTR lpszFilter = "Log Files\0*.LOG\0\0"; CHOOSEFONTA cf; CHOOSEFONTW cfW; HMODULE hMod; /* flag used for ChooseFontExA, ChooseFontExW and ChooseFontX : */ #define CHF_DESIGNVECTOR 0x0001 FARPROC lpfnChooseFont, lpfnChooseFontEx; int len; WCHAR lfFaceNameW[LF_FACESIZE]; switch( msg ) { case WM_CREATE: lstrcpy( elfdvA.elfEnumLogfontEx.elfLogFont.lfFaceName, "Arial" ); elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = 10; pdlg.lStructSize = sizeof(pdlg); pdlg.hwndOwner = hwnd; pdlg.hDevMode = NULL; pdlg.hDevNames = NULL; pdlg.Flags = PD_RETURNDEFAULT; PrintDlg( &pdlg ); dwRGBBackground = RGB( 255, 0, 255 ); szINIFile[0] = '\0'; // Compose INI File Name _getcwd( szINIFile, sizeof(szINIFile) ); strcat( szINIFile, "\\FONTTEST.INI" ); lstrcpy( szLogFile, "FONTTEST.LOG" ); wMode = (UINT)GetPrivateProfileInt( "Options", "Program Mode", IDM_STRINGMODE, szINIFile ); wTextAlign = (WORD)GetPrivateProfileInt( "Options", "TextAlign", TA_BOTTOM | TA_LEFT, szINIFile ); iBkMode = (WORD)GetPrivateProfileInt( "Options", "BkMode", OPAQUE, szINIFile ); wETO = (DWORD)GetPrivateProfileInt( "Options", "ETO Options", 0, szINIFile ); wSpacing = (UINT)GetPrivateProfileInt( "Options", "Spacing", IDM_USEDEFAULTSPACING, szINIFile ); wKerning = (UINT)GetPrivateProfileInt( "Options", "Kerning", IDM_NOKERNING, szINIFile ); wUpdateCP = (WORD)GetPrivateProfileInt( "Options", "UpdateCP", FALSE, szINIFile ); wUsePrinterDC = (WORD)GetPrivateProfileInt( "Options", "UsePrinterDC", FALSE, szINIFile ); wCharCoding = (UINT)GetPrivateProfileInt( "Options", "CharCoding", IDM_CHARCODING_MBCS, szINIFile ); if (wCharCoding == IDM_CHARCODING_UNICODE) { wCharCoding = IDM_CHARCODING_MBCS; // to be changed in ChangeCharCoding ChangeCharCoding (hwnd, IDM_CHARCODING_UNICODE); } else { wCharCoding = IDM_CHARCODING_UNICODE; // to be changed in ChangeCharCoding ChangeCharCoding (hwnd, IDM_CHARCODING_MBCS); } wMappingMode = (UINT)GetPrivateProfileInt( "Mapping", "Mode", IDM_MMTEXT, szINIFile ); hMenu = GetMenu( hwnd ); CheckMenuItem( hMenu, wSpacing, MF_CHECKED ); CheckMenuItem( hMenu, wMappingMode, MF_CHECKED ); CheckMenuItem( hMenu, wKerning, MF_CHECKED ); CheckMenuItem( hMenu, IDM_UPDATECP, (wUpdateCP ? MF_CHECKED : MF_UNCHECKED) ); CheckMenuItem( hMenu, IDM_USEPRINTERDC, (wUsePrinterDC ? MF_CHECKED : MF_UNCHECKED) ); if( wSpacing == IDM_USEDEFAULTSPACING ) { EnableMenuItem( hMenu, IDM_NOKERNING, MF_GRAYED ); EnableMenuItem( hMenu, IDM_APIKERNING, MF_GRAYED ); EnableMenuItem( hMenu, IDM_ESCAPEKERNING, MF_GRAYED ); } xWE = (int)GetPrivateProfileInt( "Mapping", "xWE", 1, szINIFile ); yWE = (int)GetPrivateProfileInt( "Mapping", "yWE", 1, szINIFile ); xWO = (int)GetPrivateProfileInt( "Mapping", "xWO", 0, szINIFile ); yWO = (int)GetPrivateProfileInt( "Mapping", "yWO", 0, szINIFile ); xVE = (int)GetPrivateProfileInt( "Mapping", "xVE", 1, szINIFile ); yVE = (int)GetPrivateProfileInt( "Mapping", "yVE", 1, szINIFile ); xVO = (int)GetPrivateProfileInt( "Mapping", "xVO", 0, szINIFile ); yVO = (int)GetPrivateProfileInt( "Mapping", "yVO", 0, szINIFile ); bAdvanced = (int)GetPrivateProfileInt( "Mapping", "Advanced", bAdvanced, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight = (int) GetPrivateProfileInt( "Font", "lfHeight", 10, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfWidth = (int) GetPrivateProfileInt( "Font", "lfWidth", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfEscapement = (int) GetPrivateProfileInt( "Font", "lfEscapement", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfOrientation = (int) GetPrivateProfileInt( "Font", "lfOrientation", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfWeight = (int) GetPrivateProfileInt( "Font", "lfWeight", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfItalic = (BYTE)GetPrivateProfileInt( "Font", "lfItalic", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfUnderline = (BYTE)GetPrivateProfileInt( "Font", "lfUnderline", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfStrikeOut = (BYTE)GetPrivateProfileInt( "Font", "lfStrikeOut", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfCharSet = (BYTE)GetPrivateProfileInt( "Font", "lfCharSet", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfOutPrecision = (BYTE)GetPrivateProfileInt( "Font", "lfOutPrecision", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfClipPrecision = (BYTE)GetPrivateProfileInt( "Font", "lfClipPrecision", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality = (BYTE)GetPrivateProfileInt( "Font", "lfQuality", 0, szINIFile ); elfdvA.elfEnumLogfontEx.elfLogFont.lfPitchAndFamily = (BYTE)GetPrivateProfileInt( "Font", "lfPitchAndFamily", 0, szINIFile ); GetPrivateProfileString( "Font", "lfFaceName", "Arial", elfdvA.elfEnumLogfontEx.elfLogFont.lfFaceName, sizeof(elfdvA.elfEnumLogfontEx.elfLogFont.lfFaceName), szINIFile ); len = (int)GetPrivateProfileInt( "Font", "lfFaceNameWlength", 0, szINIFile); if (len > 0) GetPrivateProfileStruct( "Font", "lfFaceNameW", (LPVOID)lfFaceNameW, 2*(len+1), szINIFile); else lfFaceNameW[0] = L'\0'; SyncElfdvAtoW (&elfdvW, &elfdvA); if (!isCharCodingUnicode) ; // do nothing else { wcscpy (elfdvW.elfEnumLogfontEx.elfLogFont.lfFaceName, (LPWSTR)lfFaceNameW); SyncElfdvWtoA (&elfdvA, &elfdvW); } dwRGBText = GetPrivateProfileDWORD( "Colors", "dwRGBText", dwRGBText, szINIFile ); dwRGBBackground = GetPrivateProfileDWORD( "Colors", "dwRGBBackground", dwRGBBackground, szINIFile ); GetPrivateProfileString( "View", "szString", "Font Test", szStringA, sizeof(szStringA), szINIFile ); len = (int)GetPrivateProfileInt( "View", "szStringWlength", 0, szINIFile); if (len > 0) GetPrivateProfileStruct( "View", "szStringW", (LPVOID)szStringW, 2*(len+1), szINIFile); else szStringW[0] = L'\0'; if (!isCharCodingUnicode) SyncszStringWith(IDM_CHARCODING_UNICODE); else SyncszStringWith(IDM_CHARCODING_MBCS); isGradientBackground = (BOOL) GetPrivateProfileInt("Options", "GradientBackground", FALSE, szINIFile); CheckMenuItem( hMenu, IDM_SETSOLIDBACKGROUND, (isGradientBackground ? MF_UNCHECKED : MF_CHECKED) ); CheckMenuItem( hMenu, IDM_SETGRADIENTBACKGROUND, (isGradientBackground ? MF_CHECKED : MF_UNCHECKED) ); dwRGBSolidBackgroundColor = GetPrivateProfileDWORD("Color", "dwRGBSolidBackgroundColor", RGB(0xff, 0xff, 0xff) , szINIFile); dwRGBLeftBackgroundColor = GetPrivateProfileDWORD("Color", "dwRGBLeftBackgroundColor", RGB(0xff, 0xff, 0xff), szINIFile); dwRGBRightBackgroundColor = GetPrivateProfileDWORD("Color", "dwRGBRightBackgroundColor", RGB(0, 0, 0), szINIFile); PostMessage( hwnd, WM_USER, 0, 0 ); return 0; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc; hdc = BeginPaint(hwnd,&ps); PatBlt( hdc , ps.rcPaint.left , ps.rcPaint.top , ps.rcPaint.right - ps.rcPaint.left , ps.rcPaint.bottom - ps.rcPaint.top , WHITENESS ); EndPaint(hwnd, &ps); } return 0; case WM_LBUTTONDOWN: ResizeProc( hwnd ); break; case WM_USER: VersionSpecifics( hwnd ); SelectMode( hwnd, wMode ); break; #if 0 case WM_SIZE: { int cxClient, cyClient; cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); MoveWindow( hwndGlyph, 0, 0, rcl.left, cyClient, FALSE ); MoveWindow( hwndRings, 0, 0, rcl.left, cyClient, FALSE ); MoveWindow( hwndString, 0, 0, rcl.left, cyClient, FALSE ); MoveWindow( hwndWaterfall, 0, 0, rcl.left, cyClient, FALSE ); MoveWindow( hwndWhirl, 0, 0, rcl.left, cyClient, FALSE ); MoveWindow( hwndAnsiSet, 0, 0, rcl.left, cyClient, FALSE ); MoveWindow( hwndGlyphSet, 0, 0, rcl.left, cyClient, FALSE ); InvalidateRect( hwndMode, NULL, TRUE ); InvalidateRect( hwndMain, &rcl, TRUE ); MoveWindow( hwndDebug, rcl.right, 0, rclMain.right-rcl.right, rclMain.bottom, TRUE ); } break; #endif case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDM_DEBUG: hMenu = GetMenu( hwnd ); Debugging = !Debugging; iCount = 0; SendMessage( hwndDebug, LB_RESETCONTENT, 0, 0 ); //ShowWindow( hwndDebug, Debugging ? SW_SHOWNORMAL: SW_HIDE ); CheckMenuItem( hMenu, IDM_DEBUG, Debugging ? MF_CHECKED : MF_UNCHECKED ); return 0; case IDM_OPENLOG: lstrcpy( szNewLog, szLogFile ); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.lpstrFilter = lpszFilter; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0L; ofn.nFilterIndex = 0L; ofn.lpstrFile = szNewLog; ofn.nMaxFile = sizeof(szNewLog); ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0L; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = "Log Filename"; ofn.Flags = OFN_OVERWRITEPROMPT; ofn.lpstrDefExt = "LOG"; ofn.lCustData = 0; if( GetSaveFileName( &ofn ) ) { int fh; bLogging = TRUE; lstrcpy( szLogFile, szNewLog ); dprintf( "szNewLog = '%s'", szNewLog ); // OpenFile( szLogFile, NULL, OF_DELETE ); fh = _lcreat( szLogFile, 0 ); // Nuke any existing log _lclose( fh ); hMenu = GetMenu( hwnd ); EnableMenuItem( hMenu, IDM_OPENLOG, MF_GRAYED ); EnableMenuItem( hMenu, IDM_CLOSELOG, MF_ENABLED ); } return 0; case IDM_CLOSELOG: bLogging = FALSE; hMenu = GetMenu( hwnd ); EnableMenuItem( hMenu, IDM_OPENLOG, MF_ENABLED ); EnableMenuItem( hMenu, IDM_CLOSELOG, MF_GRAYED ); return 0; case IDM_CLEARSTRING: szStringA[0] = '\0'; szStringW[0] = L'\0'; InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_EDITSTRING: ShowDialogBox( StringEditDlgProc, IDB_EDITSTRING, 0 ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_EDITGLYPHINDEX: ShowDialogBox( GlyphIndexEditDlgProc, IDB_EDITGLYPHINDEX, 0 ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_CLEARDEBUG: iCount = 0; SendMessage( hwndDebug, LB_RESETCONTENT, 0, 0 ); return 0; case IDM_PRINT: PrintIt(hwnd); break; case IDM_PRINTERSETUP: if( hdcCachedPrinter ) { DeleteDC( hdcCachedPrinter ); hdcCachedPrinter = NULL; } pdlg.Flags = PD_NOPAGENUMS | PD_PRINTSETUP | PD_USEDEVMODECOPIES; if( !PrintDlg( &pdlg ) ) { DWORD dwErr; dwErr = CommDlgExtendedError(); if( dwErr == PDERR_DEFAULTDIFFERENT ) { LPDEVNAMES lpdn; lpdn = (LPDEVNAMES)GlobalLock( pdlg.hDevNames ); lpdn->wDefault &= ~DN_DEFAULTPRN; GlobalUnlock( pdlg.hDevNames ); if( !PrintDlg( &pdlg ) ) dwErr = CommDlgExtendedError(); else dwErr = 0; lpdn = (LPDEVNAMES)GlobalLock( pdlg.hDevNames ); lpdn->wDefault |= DN_DEFAULTPRN; GlobalUnlock( pdlg.hDevNames ); } if( dwErr ) dprintf( "PrinterDlg error: 0x%.8lX", dwErr ); } if( wUsePrinterDC ) InvalidateRect( hwndMode, NULL, TRUE ); break; case IDM_GLYPHMODE: case IDM_NATIVEMODE: case IDM_BEZIERMODE: case IDM_RINGSMODE: case IDM_STRINGMODE: case IDM_WATERFALLMODE: case IDM_WHIRLMODE: case IDM_ANSISETMODE: case IDM_GLYPHSETMODE: case IDM_WIDTHSMODE: SelectMode( hwnd, wParam ); return 0; case IDM_GGOMATRIX: ShowDialogBox( GGOMatrixDlgProc, IDB_GGOMATRIX, 0 ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_WRITEGLYPH: WriteGlyph( "GLYPH.BMP" ); return 0; case IDM_USEGLYPHINDEX: hMenu = GetMenu( hwnd ); wUseGlyphIndex = !wUseGlyphIndex; CheckMenuItem( hMenu, (UINT)wParam, (wUseGlyphIndex ? MF_CHECKED : MF_UNCHECKED) ); if (wUseGlyphIndex) wETO |= ETO_GLYPH_INDEX; else wETO &= ~ETO_GLYPH_INDEX; InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_USEPRINTERDC: hMenu = GetMenu( hwnd ); wUsePrinterDC = !wUsePrinterDC; CheckMenuItem( hMenu, (UINT)wParam, (wUsePrinterDC ? MF_CHECKED : MF_UNCHECKED) ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_CHARCODING_MBCS: case IDM_CHARCODING_UNICODE: ChangeCharCoding( hwnd, wParam ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_MMHIENGLISH: case IDM_MMLOENGLISH: case IDM_MMHIMETRIC: case IDM_MMLOMETRIC: case IDM_MMTEXT: case IDM_MMTWIPS: ChangeMapMode( hwnd, wParam ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_MMANISOTROPIC: ShowDialogBox( MMAnisotropicDlgProc, IDB_MMANISOTROPIC, NULL ); ChangeMapMode( hwnd, wParam ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_COMPATIBLE_MODE: hMenu = GetMenu(hwnd); bAdvanced = FALSE; CheckMenuItem(hMenu, IDM_COMPATIBLE_MODE, MF_CHECKED); CheckMenuItem(hMenu, IDM_ADVANCED_MODE, MF_UNCHECKED); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_ADVANCED_MODE: hMenu = GetMenu(hwnd); bAdvanced = TRUE; CheckMenuItem(hMenu, IDM_COMPATIBLE_MODE, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ADVANCED_MODE, MF_CHECKED); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_WORLD_TRANSFORM: ShowDialogBox( SetWorldTransformDlgProc, IDB_SETWORLDTRANSFORM, NULL); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_CLIPELLIPSE: hMenu = GetMenu( hwnd ); bClipEllipse = !bClipEllipse; CheckMenuItem( hMenu, (UINT)wParam, (bClipEllipse ? MF_CHECKED : MF_UNCHECKED) ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_CLIPPOLYGON: hMenu = GetMenu( hwnd ); bClipPolygon = !bClipPolygon; CheckMenuItem( hMenu, (UINT)wParam, (bClipPolygon ? MF_CHECKED : MF_UNCHECKED) ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_CLIPRECTANGLE: hMenu = GetMenu( hwnd ); bClipRectangle = !bClipRectangle; CheckMenuItem( hMenu, (UINT)wParam, (bClipRectangle ? MF_CHECKED : MF_UNCHECKED) ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_CHOOSEFONTDIALOG: wtMode = (UINT)wMappingMode; ChangeMapMode( hwnd, IDM_MMTEXT ); if (!isCharCodingUnicode) { cf.lStructSize = sizeof(CHOOSEFONTA); cf.hwndOwner = hwnd; cf.lpLogFont = (LPLOGFONTA)&elfdvA; cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_MM_DESIGNVECTOR; // cf.Flags = CF_PRINTERFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT; cf.hDC = NULL; if( wUsePrinterDC ) { cf.hDC = CreatePrinterDC(); cf.Flags |= CF_BOTH; } hMod = LoadLibrary("comdlg32mm.dll"); if ((hMod) && (lpfnChooseFont = GetProcAddress(hMod, "ChooseFontA"))) { dprintf("Calling alternate ChooseFontA() function"); lpfnChooseFont( &cf ); FreeLibrary(hMod); } else { dprintf("Failed to load new library."); dprintf("Calling standard ChooseFontA() function"); ChooseFontA( &cf ); } dprintf("Resetting values of MM Axes"); elfdvA.elfDesignVector.dvNumAxes = 0; // reset to avoid errors if( cf.hDC ) { DeleteTestIC( cf.hDC ); cf.hDC = NULL; } dwRGBText = cf.rgbColors; SyncElfdvAtoW (&elfdvW, &elfdvA); } else { cfW.lStructSize = sizeof(CHOOSEFONTW); cfW.hwndOwner = hwnd; cfW.lpLogFont = (LPLOGFONTW)&elfdvW; cfW.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_MM_DESIGNVECTOR; cfW.hDC = NULL; if( wUsePrinterDC ) { cfW.hDC = CreatePrinterDC(); cfW.Flags |= CF_BOTH; } hMod = LoadLibrary("comdlg32mm.dll"); if ((hMod) && (lpfnChooseFont = GetProcAddress(hMod, "ChooseFontW"))) { dprintf("Calling alternate ChooseFontW() function"); lpfnChooseFont( &cfW ); FreeLibrary(hMod); } else { dprintf("Failed to load new library."); dprintf("Calling standard ChooseFontW() function"); ChooseFontW( &cfW ); } dprintf("Resetting values of MM Axes"); elfdvW.elfDesignVector.dvNumAxes = 0; // reset to avoid errors if( cfW.hDC ) { DeleteTestIC( cfW.hDC ); cfW.hDC = NULL; } dwRGBText = cfW.rgbColors; SyncElfdvWtoA (&elfdvA, &elfdvW); } ChangeMapMode( hwnd, wtMode ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_CHOOSEFONTDIALOGEX: wtMode = (UINT)wMappingMode; ChangeMapMode( hwnd, IDM_MMTEXT ); if (!isCharCodingUnicode) { cf.lStructSize = sizeof(CHOOSEFONTA); cf.hwndOwner = hwnd; cf.lpLogFont = (LPLOGFONTA)&elfdvA; cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_MM_DESIGNVECTOR; // cf.Flags = CF_PRINTERFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT; cf.hDC = NULL; if( wUsePrinterDC ) { cf.hDC = CreatePrinterDC(); cf.Flags |= CF_BOTH; } hMod = LoadLibrary("comdlg32mm.dll"); if ((hMod) && (lpfnChooseFontEx = GetProcAddress(hMod, "ChooseFontExA"))) { dprintf("Calling ChooseFontExA() function"); lpfnChooseFontEx( &cf, CHF_DESIGNVECTOR ); FreeLibrary(hMod); } else { dprintf("Failed to load new library."); dprintf("Calling standard ChooseFontA() function"); ChooseFontA( &cf ); dprintf("Resetting values of MM Axes"); elfdvA.elfDesignVector.dvNumAxes = 0; // reset to avoid errors } if( cf.hDC ) { DeleteTestIC( cf.hDC ); cf.hDC = NULL; } dwRGBText = cf.rgbColors; SyncElfdvAtoW (&elfdvW, &elfdvA); } else { cfW.lStructSize = sizeof(CHOOSEFONTW); cfW.hwndOwner = hwnd; cfW.lpLogFont = (LPLOGFONTW)&elfdvW; cfW.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_MM_DESIGNVECTOR; cfW.hDC = NULL; if( wUsePrinterDC ) { cfW.hDC = CreatePrinterDC(); cfW.Flags |= CF_BOTH; } hMod = LoadLibrary("comdlg32mm.dll"); if ((hMod) && (lpfnChooseFontEx = GetProcAddress(hMod, "ChooseFontExW"))) { dprintf("Calling ChooseFontExW() function"); lpfnChooseFontEx( &cfW, CHF_DESIGNVECTOR ); FreeLibrary(hMod); } else { dprintf("Failed to load new library."); dprintf("Calling standard ChooseFontW() function"); ChooseFontW( &cfW ); dprintf("Resetting values of MM Axes"); elfdvW.elfDesignVector.dvNumAxes = 0; // reset to avoid errors } if( cfW.hDC ) { DeleteTestIC( cfW.hDC ); cfW.hDC = NULL; } dwRGBText = cfW.rgbColors; SyncElfdvWtoA (&elfdvA, &elfdvW); } ChangeMapMode( hwnd, wtMode ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_CREATEFONTDIALOG: if (!isCharCodingUnicode) ShowDialogBox( CreateFontDlgProcA, IDB_CREATEFONT, NULL ); else ShowDialogBox( CreateFontDlgProcW, IDB_CREATEFONT, NULL ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_ANSIFIXEDFONT: case IDM_ANSIVARFONT: case IDM_DEVICEDEFAULTFONT: case IDM_OEMFIXEDFONT: case IDM_SYSTEMFONT: case IDM_SYSTEMFIXEDFONT: case IDM_DEFAULTGUIFONT: UseStockFont( (WORD) wParam ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_GCP : ShowDialogBox( GcpDlgProc, IDB_GCP, NULL); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_GTEEXT : ShowDialogBox( GTEExtDlgProc, IDB_GTEEXT, NULL); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_SETXTCHAR : ShowDialogBox( SetTxtChExDlgProc, IDB_SETXTCHAR, NULL ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_SETXTJUST : ShowDialogBox( SetTxtJustDlgProc, IDB_SETXTJUST, NULL ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_SETTEXTCOLOR: case IDM_SETBACKGROUNDCOLOR: case IDM_SETSOLIDBACKGROUNDCOLOR: case IDM_SETLEFTGRADIENTCOLOR: case IDM_SETRIGHTGRADIENTCOLOR: { int i; CHOOSECOLOR cc; DWORD dwCustom[16]; for( i = 0; i < 16; i++ ) dwCustom[i] = RGB(255,255,255); memset( &cc, 0, sizeof(cc) ); cc.lStructSize = sizeof(cc); cc.hwndOwner = hwnd; cc.rgbResult = ( wParam==IDM_SETTEXTCOLOR ? dwRGBText : dwRGBBackground ); cc.lpCustColors = (LPDWORD)dwCustom; cc.Flags = CC_RGBINIT; if( ChooseColor(&cc) ) { switch(wParam) { case IDM_SETTEXTCOLOR: dwRGBText = cc.rgbResult; break; case IDM_SETBACKGROUNDCOLOR: dwRGBBackground = cc.rgbResult; break; case IDM_SETSOLIDBACKGROUNDCOLOR: dwRGBSolidBackgroundColor = cc.rgbResult; break; case IDM_SETLEFTGRADIENTCOLOR: dwRGBLeftBackgroundColor = cc.rgbResult; break; case IDM_SETRIGHTGRADIENTCOLOR: dwRGBRightBackgroundColor = cc.rgbResult; break; } InvalidateRect( hwndMode, NULL, TRUE ); } } return 0; case IDM_SHOWLOGFONT: ShowLogFont(); return 0; case IDM_USEDEFAULTSPACING: case IDM_USEWIDTHSPACING: case IDM_USEABCSPACING: case IDM_PDX: case IDM_PDXPDY: case IDM_RANDOMPDXPDY: hMenu = GetMenu( hwnd ); if (wUseGlyphIndex != 0) if (wParam == IDM_USEWIDTHSPACING || wParam == IDM_USEABCSPACING) { MessageBox(hwnd, "You cannot choose this option together with using glyph indices!", "Error", MB_OK); return 0; } if (wParam == IDM_PDX && wSpacing == IDM_PDXPDY) { if (lpintdx) { for (i=0; i=0; i--) { lpintdx[2*i] = lpintdx[i]; lpintdx[2*i+1] = 0; } sizePdx *= 2; } } // make the actual switch now CheckMenuItem( hMenu, wSpacing, MF_UNCHECKED ); CheckMenuItem( hMenu, (UINT)wParam, MF_CHECKED ); wSpacing = (UINT)wParam; if ((wSpacing == IDM_PDXPDY) || (wSpacing == IDM_RANDOMPDXPDY)) wETO |= ETO_PDY; else wETO &= ~ETO_PDY; if((wSpacing == IDM_USEDEFAULTSPACING) || (wSpacing == IDM_PDXPDY) || (wSpacing == IDM_RANDOMPDXPDY)) { EnableMenuItem( hMenu, IDM_NOKERNING, MF_GRAYED ); EnableMenuItem( hMenu, IDM_APIKERNING, MF_GRAYED ); EnableMenuItem( hMenu, IDM_ESCAPEKERNING, MF_GRAYED ); } else { EnableMenuItem( hMenu, IDM_NOKERNING, MF_ENABLED ); EnableMenuItem( hMenu, IDM_APIKERNING, MF_ENABLED ); EnableMenuItem( hMenu, IDM_ESCAPEKERNING, MF_ENABLED ); } InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_NOKERNING: case IDM_APIKERNING: case IDM_ESCAPEKERNING: hMenu = GetMenu( hwnd ); CheckMenuItem( hMenu, wKerning, MF_UNCHECKED ); CheckMenuItem( hMenu, (UINT)wParam, MF_CHECKED ); wKerning = (UINT)wParam; InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_UPDATECP: hMenu = GetMenu( hwnd ); wUpdateCP = !wUpdateCP; CheckMenuItem( hMenu, (UINT)wParam, (wUpdateCP ? MF_CHECKED : MF_UNCHECKED) ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_ENUMFONTS: ShowEnumFonts( hwnd ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_ENUMFONTFAMILIES: ShowEnumFontFamilies( hwnd ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; case IDM_ENUMFONTFAMILIESEX: ShowEnumFontFamiliesEx( hwnd); InvalidateRect( hwndMode, NULL, TRUE); return 0; case IDM_GETEXTENDEDTEXTMETRICS: ShowExtendedTextMetrics( hwnd ); return 0; case IDM_GETPAIRKERNTABLE: ShowPairKerningTable( hwnd ); return 0; case IDM_GETOUTLINETEXTMETRICS: ShowOutlineTextMetrics( hwnd ); return 0; case IDM_GETRASTERIZERCAPS: ShowRasterizerCaps(); return 0; case IDM_GETTEXTEXTENT: ShowTextExtent( hwnd ); return 0; case IDM_GETUNICODERANGES: ShowFontUnicodeRanges( hwnd ); return 0; case IDM_GETTEXTEXTENTI: ShowTextExtentI( hwnd ); return 0; case IDM_GETCHARWIDTHI: ShowCharWidthI( hwnd ); return 0; case IDM_GETTEXTFACE: ShowTextFace( hwnd ); return 0; case IDM_GETTEXTMETRICS: ShowTextMetrics( hwnd ); return 0; case IDM_GETTEXTCHARSETINFO: ShowTextCharsetInfo( hwnd ); return 0; case IDM_GETFONTLANGUAGEINFO: ShowFontLanguageInfo( hwnd ); return 0; case IDM_GETFONTDATA: ShowDialogBox( GetFontDataDlgProc, IDB_GETFONTDATA, NULL ); return 0; case IDM_CREATESCALABLEFONTRESOURCE: ShowDialogBox( CreateScalableFontDlgProc, IDB_CREATESCALABLEFONTRESOURCE, NULL ); return 0; case IDM_ADDFONTRESOURCE: ShowDialogBox( AddFontResourceDlgProc, IDB_ADDFONTRESOURCE, NULL ); return 0; case IDM_ADDFONTRESOURCEEX: ShowDialogBox( AddFontResourceExDlgProc, IDB_ADDFONTRESOURCEEX, NULL); return 0; case IDM_REMOVEFONTRESOURCE: ShowDialogBox( RemoveFontResourceDlgProc, IDB_REMOVEFONTRESOURCE, NULL ); return 0; case IDM_REMOVEFONTRESOURCEEX: ShowDialogBox( RemoveFontResourceExDlgProc, IDB_REMOVEFONTRESOURCEEX, NULL ); return 0; case IDM_ADDFONTMEMRESOURCEEX: //ShowAddFontMemResourceEx(hwnd); ShowDialogBox(AddFontMemResourceExDlgProc, IDB_ADDFONTMEMRESOURCEEX, NULL); return 0; case IDM_REMOVEFONTMEMRESOURCEEX: //ShowRemoveFontMemResourceEx(hwnd); ShowDialogBox(RemoveFontMemResourceExDlgProc, IDB_REMOVEFONTMEMRESOURCEEX, NULL); return 0; case IDM_SETTEXTOUTOPTIONS: ShowDialogBox( SetTextOutOptionsDlgProc, IDB_TEXTOUTOPTIONS, NULL ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; #ifdef USERGETCHARWIDTH case IDM_GETCHARWIDTHINFO: ShowCharWidthInfo( hwnd ); return 0; #endif #ifdef USERGETWVTPERF case IDM_GETWVTPERF: ShowDialogBox( GetWVTPerfDlgProc, IDB_GETWVTPERF, NULL); return 0; #endif #ifdef GI_API case IDM_TEXTOUTPERF: TextOutPerformance( hwnd ); return 0; case IDM_CLEARTYPEPERF: ClearTypePerformance( hwnd ); return 0; #endif case IDM_GETKERNINGPAIRS: GetKerningPairsDlgProc( hwnd ); return 0; case IDM_ENABLEEUDC: ShowEnableEudc( hwnd ); return 0; case IDM_EUDCLOADLINKW: ShowDialogBox(EudcLoadLinkWDlgProc, IDB_EUDCLOADLINKW, NULL); return 0; case IDM_EUDCUNLOADLINKW: ShowDialogBox(EudcUnLoadLinkWDlgProc, IDB_EUDCUNLOADLINKW, NULL); return 0; case IDM_GETEUDCTIMESTAMP: ShowGetEudcTimeStamp( hwnd ); return 0; case IDM_GETEUDCTIMESTAMPEXW: ShowGetEudcTimeStampExW( hwnd ); return 0; case IDM_GETSTRINGBITMAPA: ShowDialogBox(ShowGetStringBitMapAProc, IDB_GETSTRINGBITMAPA, NULL); return 0; case IDM_GETSTRINGBITMAPW: ShowDialogBox(ShowGetStringBitMapWProc, IDB_GETSTRINGBITMAPW, NULL); return 0; case IDM_GETFONTASSOCSTATUS: ShowGetFontAssocStatus (hwnd ); return 0; case IDM_CHARWIDTHTEST: CharWidthTestForAntiAliasing( hwnd, &elfdvA.elfEnumLogfontEx.elfLogFont ); return 0; case IDM_CHARWIDTHTESTALL: CharWidthTestAllForAntiAliasing( hwnd ); return 0; case IDM_SETSOLIDBACKGROUND: case IDM_SETGRADIENTBACKGROUND: hMenu = GetMenu( hwnd ); isGradientBackground = (wParam == IDM_SETGRADIENTBACKGROUND); CheckMenuItem( hMenu, IDM_SETSOLIDBACKGROUND, (isGradientBackground ? MF_UNCHECKED : MF_CHECKED) ); CheckMenuItem( hMenu, IDM_SETGRADIENTBACKGROUND, (isGradientBackground ? MF_CHECKED : MF_UNCHECKED) ); InvalidateRect( hwndMode, NULL, TRUE ); return 0; default: return 0; } case WM_MOUSEACTIVATE: case WM_SETFOCUS: SetFocus( hwndMode ); return 0; case WM_DESTROY: if( hdcCachedPrinter ) DeleteDC( hdcCachedPrinter ); WritePrivateProfileInt( "Font", "lfHeight", elfdvA.elfEnumLogfontEx.elfLogFont.lfHeight, szINIFile ); WritePrivateProfileInt( "Font", "lfWidth", elfdvA.elfEnumLogfontEx.elfLogFont.lfWidth, szINIFile ); WritePrivateProfileInt( "Font", "lfEscapement", elfdvA.elfEnumLogfontEx.elfLogFont.lfEscapement, szINIFile ); WritePrivateProfileInt( "Font", "lfOrientation", elfdvA.elfEnumLogfontEx.elfLogFont.lfOrientation, szINIFile ); WritePrivateProfileInt( "Font", "lfWeight", elfdvA.elfEnumLogfontEx.elfLogFont.lfWeight, szINIFile ); WritePrivateProfileInt( "Font", "lfItalic", elfdvA.elfEnumLogfontEx.elfLogFont.lfItalic, szINIFile ); WritePrivateProfileInt( "Font", "lfUnderline", elfdvA.elfEnumLogfontEx.elfLogFont.lfUnderline, szINIFile ); WritePrivateProfileInt( "Font", "lfStrikeOut", elfdvA.elfEnumLogfontEx.elfLogFont.lfStrikeOut, szINIFile ); WritePrivateProfileInt( "Font", "lfCharSet", elfdvA.elfEnumLogfontEx.elfLogFont.lfCharSet, szINIFile ); WritePrivateProfileInt( "Font", "lfOutPrecision", elfdvA.elfEnumLogfontEx.elfLogFont.lfOutPrecision, szINIFile ); WritePrivateProfileInt( "Font", "lfClipPrecision", elfdvA.elfEnumLogfontEx.elfLogFont.lfClipPrecision, szINIFile ); WritePrivateProfileInt( "Font", "lfQuality", elfdvA.elfEnumLogfontEx.elfLogFont.lfQuality, szINIFile ); WritePrivateProfileInt( "Font", "lfPitchAndFamily", elfdvA.elfEnumLogfontEx.elfLogFont.lfPitchAndFamily, szINIFile ); WritePrivateProfileString( "Font", "lfFaceName", elfdvA.elfEnumLogfontEx.elfLogFont.lfFaceName, szINIFile ); WritePrivateProfileInt( "Font", "lfFaceNameWlength", wcslen(elfdvW.elfEnumLogfontEx.elfLogFont.lfFaceName), szINIFile ); WritePrivateProfileStruct( "Font", "lfFaceNameW", (LPVOID)elfdvW.elfEnumLogfontEx.elfLogFont.lfFaceName, 2*(wcslen(elfdvW.elfEnumLogfontEx.elfLogFont.lfFaceName)+1), szINIFile); WritePrivateProfileDWORD( "Colors", "dwRGBText", dwRGBText, szINIFile ); WritePrivateProfileDWORD( "Colors", "dwRGBBackground", dwRGBBackground, szINIFile ); WritePrivateProfileDWORD( "Colors", "dwRGBSolidBackgroundColor", dwRGBSolidBackgroundColor, szINIFile ); WritePrivateProfileDWORD( "Colors", "dwRGBLeftBackgroundColor", dwRGBLeftBackgroundColor, szINIFile ); WritePrivateProfileDWORD( "Colors", "dwRGBRightBackgroundColor", dwRGBRightBackgroundColor, szINIFile ); WritePrivateProfileInt( "Options", "Program Mode", wMode, szINIFile ); WritePrivateProfileInt( "Options", "TextAlign", wTextAlign, szINIFile ); WritePrivateProfileInt( "Options", "BkMode", iBkMode, szINIFile ); WritePrivateProfileInt( "Options", "ETO Options", wETO, szINIFile ); WritePrivateProfileInt( "Options", "Spacing", wSpacing, szINIFile ); WritePrivateProfileInt( "Options", "Kerning", wKerning, szINIFile ); WritePrivateProfileInt( "Options", "UpdateCP", wUpdateCP, szINIFile ); WritePrivateProfileInt( "Options", "UsePrinterDC", wUsePrinterDC, szINIFile ); WritePrivateProfileInt( "Options", "CharCoding", wCharCoding, szINIFile ); WritePrivateProfileInt( "Options", "GradientBackground", isGradientBackground, szINIFile ); WritePrivateProfileInt( "Mapping", "Mode", (int)wMappingMode, szINIFile ); WritePrivateProfileInt( "Mapping", "xWE", xWE, szINIFile ); WritePrivateProfileInt( "Mapping", "yWE", yWE, szINIFile ); WritePrivateProfileInt( "Mapping", "xWO", xWO, szINIFile ); WritePrivateProfileInt( "Mapping", "yWO", yWO, szINIFile ); WritePrivateProfileInt( "Mapping", "xVE", xVE, szINIFile ); WritePrivateProfileInt( "Mapping", "yVE", yVE, szINIFile ); WritePrivateProfileInt( "Mapping", "xVO", xVO, szINIFile ); WritePrivateProfileInt( "Mapping", "yVO", yVO, szINIFile ); WritePrivateProfileInt( "Mapping", "Advanced", bAdvanced, szINIFile ); WritePrivateProfileString( "View", "szString", szStringA, szINIFile ); //WritePrivateProfileStringW( L"View", L"szStringW", szStringW, L"\\awork\\fonttest.tig\\fonttest.ini"); WritePrivateProfileInt( "View", "szStringWlength", wcslen(szStringW), szINIFile ); WritePrivateProfileStruct( "View", "szStringW", (LPVOID)szStringW, 2*(wcslen(szStringW)+1), szINIFile); PostQuitMessage( 0 ); return 0; } return DefWindowProc( hwnd, msg, wParam, lParam ); } //***************************************************************************** //******************* G E T D L G I T E M F L O A T ******************* //***************************************************************************** FLOAT GetDlgItemFLOAT( HWND hdlg , int id ) { char ach[50]; memset(ach,0,sizeof(ach)); return((FLOAT)(GetDlgItemText(hdlg,id,ach,sizeof(ach))?atof(ach):0.0)); } //***************************************************************************** //******************* S E T D L G I T E M F L O A T ******************* //***************************************************************************** void SetDlgItemFLOAT( HWND hdlg , int id , FLOAT e ) { static char ach[25]; ach[0] = '\0'; sprintf(ach, "%f", (double) e); SetDlgItemText(hdlg, id, ach); } //***************************************************************************** //************ SETWORLDTRANSFORM D L G P R O C ************** //***************************************************************************** INT_PTR CALLBACK SetWorldTransformDlgProc( HWND hdlg , UINT msg , WPARAM wParam , LPARAM lParam ) { switch(msg) { case WM_INITDIALOG: SetDlgItemFLOAT(hdlg, IDD_VALUE_EM11, xf.eM11); SetDlgItemFLOAT(hdlg, IDD_VALUE_EM12, xf.eM12); SetDlgItemFLOAT(hdlg, IDD_VALUE_EM21, xf.eM21); SetDlgItemFLOAT(hdlg, IDD_VALUE_EM22, xf.eM22); SetDlgItemFLOAT(hdlg, IDD_VALUE_EDX , xf.eDx ); SetDlgItemFLOAT(hdlg, IDD_VALUE_EDY , xf.eDy ); return(TRUE); case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: xf.eM11 = GetDlgItemFLOAT(hdlg, IDD_VALUE_EM11); xf.eM12 = GetDlgItemFLOAT(hdlg, IDD_VALUE_EM12); xf.eM21 = GetDlgItemFLOAT(hdlg, IDD_VALUE_EM21); xf.eM22 = GetDlgItemFLOAT(hdlg, IDD_VALUE_EM22); xf.eDx = GetDlgItemFLOAT(hdlg, IDD_VALUE_EDX ); xf.eDy = GetDlgItemFLOAT(hdlg, IDD_VALUE_EDY ); EndDialog( hdlg, TRUE ); return(TRUE); case IDCANCEL: EndDialog( hdlg, FALSE ); return TRUE; } break; case WM_CLOSE: EndDialog(hdlg, FALSE); return(TRUE); } return(FALSE); } /******************************Public*Routine******************************\ * * BOOL GenExtTextOut, text in path if so required * * History: * 19-Sep-1996 -by- Bodin Dresevic [BodinD] * Wrote it. \**************************************************************************/ BOOL GenExtTextOut( HDC hdc, int x, int y, DWORD wFlags, LPRECT lpRect, LPVOID lpszString, int cbString, LPINT lpdx ) { BOOL bRet; if (bStrokePath || bFillPath) { BeginPath(hdc); } if (!isCharCodingUnicode) bRet = ExtTextOutA(hdc, x, y, wFlags, lpRect, lpszString, cbString, lpdx); else bRet = ExtTextOutW(hdc, x, y, wFlags, lpRect, lpszString, cbString, lpdx); if (bStrokePath || bFillPath) { EndPath(hdc); if (fillMode == ALTERNATE_FILL) SetPolyFillMode(hdc, ALTERNATE); else SetPolyFillMode(hdc, WINDING); if (bStrokePath && bFillPath) StrokeAndFillPath(hdc); else if (bStrokePath) StrokePath(hdc); else FillPath(hdc); } return bRet; } //***************************************************************************** //******************* Read Design Vector ******************************* //***************************************************************************** //** This routine reads the design vector from the dialog box. BOOL fReadDesignVector( HWND hdlg, LPDESIGNVECTOR lpdvMMInfo) { UINT i; lpdvMMInfo->dvNumAxes= GetDlgItemDWORD( hdlg, IDC_NUMEDITAXES); // currently, we do not support more than 4 axes though // the API supports upto 16 axes. if (lpdvMMInfo->dvNumAxes > 4) { MessageBox(hdlg, "Number of Axes should be <= 4", NULL, MB_OK | MB_ICONSTOP | MB_APPLMODAL); EndDialog(hdlg, FALSE); return FALSE; } for (i = 0 ; i < lpdvMMInfo->dvNumAxes; i++) { lpdvMMInfo->dvValues[i] = (LONG) GetDlgItemDWORD( hdlg, IDC_TAGVALUE1 + i*2 ); } return TRUE; } //************************************************************************// // // // Function : CreateFontIndirectWrapperW // // // // Parameters: pointer to the ENUMLOGFONTEXDEV structure. // // // // Thread safety: none. // // // // Task performed: This function calls CreateFontIndirect if the number // // of axes in the DESIGNVECTOR is zero or if the app is // // not running on NT5.0 Else, the wrapper calls the // // CreateFontIndirectEx version to create the font. // // // //************************************************************************// HFONT CreateFontIndirectWrapperW( ENUMLOGFONTEXDVW * pelfdv) { #ifndef GI_API return CreateFontIndirectW((LOGFONTW *) &(pelfdv->elfEnumLogfontEx.elfLogFont)); #else if (pelfdv->elfDesignVector.dvNumAxes) { return CreateFontIndirectExW(pelfdv); } else { return CreateFontIndirectW((LOGFONTW *) &(pelfdv->elfEnumLogfontEx.elfLogFont)); } #endif } HFONT CreateFontIndirectWrapperA( ENUMLOGFONTEXDVA * pelfdv) { #ifndef GI_API return CreateFontIndirect((LOGFONTA *) &(pelfdv->elfEnumLogfontEx.elfLogFont)); #else if (pelfdv->elfDesignVector.dvNumAxes) { return CreateFontIndirectEx(pelfdv); } else { return CreateFontIndirect((LOGFONTA *) &(pelfdv->elfEnumLogfontEx.elfLogFont)); } #endif } //***************************************************************************** //******************* SyncWith ******************************* //***************************************************************************** //* This function will synchronize Unicode and MBCS versions of szStringA/W string buffers. BOOL SyncStringsAandW (int mode, LPSTR lpszStringA, LPWSTR lpszStringW, int cch) { int nChar; int currentCP; DWORD *charSet; CHARSETINFO myCSI; if (!isCharCodingUnicode) charSet = UlongToPtr(elfdvA.elfEnumLogfontEx.elfLogFont.lfCharSet); else charSet = UlongToPtr(elfdvW.elfEnumLogfontEx.elfLogFont.lfCharSet); TranslateCharsetInfo( (DWORD *)charSet, &myCSI, TCI_SRCCHARSET); currentCP = myCSI.ciACP; // dprintf ("Selected Code Page: %d", currentCP); switch (mode) { case IDM_CHARCODING_MBCS: nChar = WideCharToMultiByte(currentCP, 0, lpszStringW, -1, lpszStringA, cch, NULL, NULL); if (nChar == 0) { dprintf ("Error with Unicode->MBCS conversion"); return FALSE; } break; case IDM_CHARCODING_UNICODE: nChar = MultiByteToWideChar(currentCP, 0, lpszStringA, -1, lpszStringW, cch); if (nChar == 0) { dprintf ("Error with MBCS ->Unicode conversion"); return FALSE; } break; default: return FALSE; } return TRUE; } //***************************************************************************** //******************* szStringSyncWith ******************************* //***************************************************************************** //* This function will synchronize Unicode and MBCS versions of szStringA/W string buffers. BOOL SyncszStringWith (int mode) { return SyncStringsAandW(mode, szStringA, szStringW, MAX_TEXT); } BOOL SyncStringAtoW (LPWSTR lpszStringW, LPSTR lpszStringA, int cch) { return SyncStringsAandW (IDM_CHARCODING_UNICODE, lpszStringA, lpszStringW, cch); } BOOL SyncStringWtoA (LPSTR lpszStringA, LPWSTR lpszStringW, int cch) { return SyncStringsAandW (IDM_CHARCODING_MBCS, lpszStringA, lpszStringW, cch); } //***************************************************************************** //**************** SyncElfdvAtoW / SyncElfdvWtoA ************************ //***************************************************************************** //* These functions synchronize Unicode and MBCS versions of elfdvA/W logfont structures. BOOL SyncElfdvAtoW (ENUMLOGFONTEXDVW *elfdv1, ENUMLOGFONTEXDVA *elfdv2) { BOOL ok = TRUE; elfdv1->elfEnumLogfontEx.elfLogFont.lfHeight = elfdv2->elfEnumLogfontEx.elfLogFont.lfHeight; elfdv1->elfEnumLogfontEx.elfLogFont.lfWidth = elfdv2->elfEnumLogfontEx.elfLogFont.lfWidth; elfdv1->elfEnumLogfontEx.elfLogFont.lfEscapement = elfdv2->elfEnumLogfontEx.elfLogFont.lfEscapement; elfdv1->elfEnumLogfontEx.elfLogFont.lfOrientation = elfdv2->elfEnumLogfontEx.elfLogFont.lfOrientation; elfdv1->elfEnumLogfontEx.elfLogFont.lfWeight = elfdv2->elfEnumLogfontEx.elfLogFont.lfWeight; elfdv1->elfEnumLogfontEx.elfLogFont.lfItalic = elfdv2->elfEnumLogfontEx.elfLogFont.lfItalic; elfdv1->elfEnumLogfontEx.elfLogFont.lfUnderline = elfdv2->elfEnumLogfontEx.elfLogFont.lfUnderline; elfdv1->elfEnumLogfontEx.elfLogFont.lfStrikeOut = elfdv2->elfEnumLogfontEx.elfLogFont.lfStrikeOut; elfdv1->elfEnumLogfontEx.elfLogFont.lfCharSet = elfdv2->elfEnumLogfontEx.elfLogFont.lfCharSet; elfdv1->elfEnumLogfontEx.elfLogFont.lfOutPrecision = elfdv2->elfEnumLogfontEx.elfLogFont.lfOutPrecision; elfdv1->elfEnumLogfontEx.elfLogFont.lfClipPrecision = elfdv2->elfEnumLogfontEx.elfLogFont.lfClipPrecision; elfdv1->elfEnumLogfontEx.elfLogFont.lfQuality = elfdv2->elfEnumLogfontEx.elfLogFont.lfQuality; elfdv1->elfEnumLogfontEx.elfLogFont.lfPitchAndFamily = elfdv2->elfEnumLogfontEx.elfLogFont.lfPitchAndFamily; ok &= SyncStringAtoW (elfdv1->elfEnumLogfontEx.elfLogFont.lfFaceName, elfdv2->elfEnumLogfontEx.elfLogFont.lfFaceName, LF_FACESIZE); ok &= SyncStringAtoW (elfdv1->elfEnumLogfontEx.elfFullName , elfdv2->elfEnumLogfontEx.elfFullName, LF_FULLFACESIZE); ok &= SyncStringAtoW (elfdv1->elfEnumLogfontEx.elfStyle , elfdv2->elfEnumLogfontEx.elfStyle , LF_FACESIZE); ok &= SyncStringAtoW (elfdv1->elfEnumLogfontEx.elfScript , elfdv2->elfEnumLogfontEx.elfScript , LF_FACESIZE); memcpy(&(elfdv1->elfDesignVector), &(elfdv2->elfDesignVector), sizeof(DESIGNVECTOR)); return ok; } //***************************************************************************** //**************** SyncElfdvAtoW / SyncElfdvWtoA ************************ //***************************************************************************** //* These functions synchronize Unicode and MBCS versions of elfdvA/W logfont structures. BOOL SyncElfdvWtoA (ENUMLOGFONTEXDVA *elfdv1, ENUMLOGFONTEXDVW *elfdv2) { BOOL ok; elfdv1->elfEnumLogfontEx.elfLogFont.lfHeight = elfdv2->elfEnumLogfontEx.elfLogFont.lfHeight; elfdv1->elfEnumLogfontEx.elfLogFont.lfWidth = elfdv2->elfEnumLogfontEx.elfLogFont.lfWidth; elfdv1->elfEnumLogfontEx.elfLogFont.lfEscapement = elfdv2->elfEnumLogfontEx.elfLogFont.lfEscapement; elfdv1->elfEnumLogfontEx.elfLogFont.lfOrientation = elfdv2->elfEnumLogfontEx.elfLogFont.lfOrientation; elfdv1->elfEnumLogfontEx.elfLogFont.lfWeight = elfdv2->elfEnumLogfontEx.elfLogFont.lfWeight; elfdv1->elfEnumLogfontEx.elfLogFont.lfItalic = elfdv2->elfEnumLogfontEx.elfLogFont.lfItalic; elfdv1->elfEnumLogfontEx.elfLogFont.lfUnderline = elfdv2->elfEnumLogfontEx.elfLogFont.lfUnderline; elfdv1->elfEnumLogfontEx.elfLogFont.lfStrikeOut = elfdv2->elfEnumLogfontEx.elfLogFont.lfStrikeOut; elfdv1->elfEnumLogfontEx.elfLogFont.lfCharSet = elfdv2->elfEnumLogfontEx.elfLogFont.lfCharSet; elfdv1->elfEnumLogfontEx.elfLogFont.lfOutPrecision = elfdv2->elfEnumLogfontEx.elfLogFont.lfOutPrecision; elfdv1->elfEnumLogfontEx.elfLogFont.lfClipPrecision = elfdv2->elfEnumLogfontEx.elfLogFont.lfClipPrecision; elfdv1->elfEnumLogfontEx.elfLogFont.lfQuality = elfdv2->elfEnumLogfontEx.elfLogFont.lfQuality; elfdv1->elfEnumLogfontEx.elfLogFont.lfPitchAndFamily = elfdv2->elfEnumLogfontEx.elfLogFont.lfPitchAndFamily; ok &= SyncStringWtoA (elfdv1->elfEnumLogfontEx.elfLogFont.lfFaceName, elfdv2->elfEnumLogfontEx.elfLogFont.lfFaceName, LF_FACESIZE); ok &= SyncStringWtoA (elfdv1->elfEnumLogfontEx.elfFullName , elfdv2->elfEnumLogfontEx.elfFullName, LF_FULLFACESIZE); ok &= SyncStringWtoA (elfdv1->elfEnumLogfontEx.elfStyle , elfdv2->elfEnumLogfontEx.elfStyle , LF_FACESIZE); ok &= SyncStringWtoA (elfdv1->elfEnumLogfontEx.elfScript , elfdv2->elfEnumLogfontEx.elfScript , LF_FACESIZE); memcpy(&(elfdv1->elfDesignVector), &(elfdv2->elfDesignVector), sizeof(DESIGNVECTOR)); return ok; }