/*++ Copyright (c) 1992 Microsoft Corporation Module Name: fontdlg.dlg Abstract: This module contains the code for console font dialog Author: Therese Stowell (thereses) Feb-3-1992 (swiped from Win3.1) Revision History: --*/ #include "precomp.h" #pragma hdrstop #include "fontdlg.h" /* ----- Prototypes ----- */ int FontListCreate( HWND hDlg, LPTSTR ptszTTFace, BOOL bNewFaceList ); BOOL PreviewUpdate( HWND hDlg, BOOL bLB ); int SelectCurrentSize( HWND hDlg, BOOL bLB, int FontIndex); BOOL PreviewInit( HWND hDlg); VOID DrawItemFontList( const LPDRAWITEMSTRUCT lpdis); /* ----- Globals ----- */ const TCHAR g_szPreviewText[] = \ TEXT("C:\\WINDOWS> dir \n") \ TEXT("SYSTEM 10-01-99 5:00a\n") \ TEXT("SYSTEM32 10-01-99 5:00a\n") \ TEXT("README TXT 26926 10-01-99 5:00a\n") \ TEXT("WINDOWS BMP 46080 10-01-99 5:00a\n") \ TEXT("NOTEPAD EXE 337232 10-01-99 5:00a\n") \ TEXT("CLOCK AVI 39594 10-01-99 5:00p\n") \ TEXT("WIN INI 7005 10-01-99 5:00a\n"); HBITMAP hbmTT = NULL; // handle of TT logo bitmap BITMAP bmTT; // attributes of TT source bitmap int dyFacelistItem; // height of Item in Facelist listbox BOOL gbPointSizeError = FALSE; BOOL gbBold = FALSE; #if defined(FE_SB) BOOL fChangeCodePage = FALSE; BOOL SelectCurrentFont( HWND hDlg, int FontIndex ); #endif // Globals strings loaded from resource TCHAR tszSelectedFont[CCH_SELECTEDFONT+1]; TCHAR tszRasterFonts[CCH_RASTERFONTS+1]; INT_PTR APIENTRY FontDlgProc( HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam ) /*++ Dialog proc for the font selection dialog box. Returns the near offset into the far table of LOGFONT structures. --*/ { HWND hWndFocus; HWND hWndList; int FontIndex; BOOL bLB; TEXTMETRIC tm; HDC hDC; switch (wMsg) { case WM_INITDIALOG: /* * Load the font description strings */ LoadString(ghInstance, IDS_RASTERFONT, tszRasterFonts, NELEM(tszRasterFonts)); DBGPRINT(("tszRasterFonts = \"%ls\"\n", tszRasterFonts)); ASSERT(_tcslen(tszRasterFonts) < CCH_RASTERFONTS); LoadString(ghInstance, IDS_SELECTEDFONT, tszSelectedFont, NELEM(tszSelectedFont)); DBGPRINT(("tszSelectedFont = \"%ls\"\n", tszSelectedFont)); ASSERT(_tcslen(tszSelectedFont) < CCH_SELECTEDFONT); /* Save current font size as dialog window's user data */ #if defined(FE_SB) ASSERT(OEMCP != 0); if (gfFESystem) { SetWindowLongPtr(hDlg, GWLP_USERDATA, MAKELONG(FontInfo[CurrentFontIndex].tmCharSet, FontInfo[CurrentFontIndex].Size.Y)); } else { #endif SetWindowLongPtr(hDlg, GWLP_USERDATA, MAKELONG(FontInfo[CurrentFontIndex].Size.X, FontInfo[CurrentFontIndex].Size.Y)); #if defined(FE_SB) } #endif /* Create the list of suitable fonts */ gbEnumerateFaces = TRUE; bLB = !TM_IS_TT_FONT(gpStateInfo->FontFamily); gbBold = IS_BOLD(gpStateInfo->FontWeight); CheckDlgButton(hDlg, IDD_BOLDFONT, gbBold); FontListCreate(hDlg, bLB ? NULL : gpStateInfo->FaceName, TRUE); /* Initialize the preview window - selects current face & size too */ bLB = PreviewInit(hDlg); PreviewUpdate(hDlg, bLB); /* Make sure the list box has the focus */ hWndList = GetDlgItem(hDlg, bLB ? IDD_PIXELSLIST : IDD_POINTSLIST); SetFocus(hWndList); break; case WM_FONTCHANGE: gbEnumerateFaces = TRUE; bLB = !TM_IS_TT_FONT(gpStateInfo->FontFamily); FontListCreate(hDlg, NULL, TRUE); FontIndex = FindCreateFont(gpStateInfo->FontFamily, gpStateInfo->FaceName, gpStateInfo->FontSize, gpStateInfo->FontWeight, gpStateInfo->CodePage); SelectCurrentSize(hDlg, bLB, FontIndex); return TRUE; #if defined(FE_SB) case WM_PAINT: if (fChangeCodePage) { fChangeCodePage = FALSE; /* Create the list of suitable fonts */ bLB = !TM_IS_TT_FONT(gpStateInfo->FontFamily); FontIndex = FontListCreate(hDlg, !bLB ? NULL : gpStateInfo->FaceName, TRUE); FontIndex = FontListCreate(hDlg, bLB ? NULL : gpStateInfo->FaceName, TRUE); CurrentFontIndex = FontIndex; FontIndex = SelectCurrentSize(hDlg, bLB, FontIndex); SelectCurrentFont(hDlg, FontIndex); PreviewUpdate(hDlg, bLB); } break; #endif case WM_COMMAND: switch (LOWORD(wParam)) { case IDD_BOLDFONT: DBGPRINT(("WM_COMMAND to Bold Font checkbox %x\n", HIWORD(wParam))); gbBold = IsDlgButtonChecked(hDlg, IDD_BOLDFONT); goto RedoFontListAndPreview; case IDD_FACENAME: switch (HIWORD(wParam)) { case LBN_SELCHANGE: RedoFontListAndPreview: { TCHAR atchNewFace[LF_FACESIZE]; LONG l; DBGFONTS(("LBN_SELCHANGE from FACENAME\n")); l = (LONG)SendDlgItemMessage(hDlg, IDD_FACENAME, LB_GETCURSEL, 0, 0L); bLB = (BOOL)SendDlgItemMessage(hDlg, IDD_FACENAME, LB_GETITEMDATA, l, 0L); if (!bLB) { SendDlgItemMessage(hDlg, IDD_FACENAME, LB_GETTEXT, l, (LPARAM)atchNewFace); DBGFONTS(("LBN_EDITUPDATE, got TT face \"%ls\"\n", atchNewFace)); } FontIndex = FontListCreate(hDlg, bLB ? NULL : atchNewFace, FALSE); FontIndex = SelectCurrentSize(hDlg, bLB, FontIndex); PreviewUpdate(hDlg, bLB); return TRUE; } } break; case IDD_POINTSLIST: switch (HIWORD(wParam)) { case CBN_SELCHANGE: DBGFONTS(("CBN_SELCHANGE from POINTSLIST\n")); PreviewUpdate(hDlg, FALSE); return TRUE; case CBN_KILLFOCUS: DBGFONTS(("CBN_KILLFOCUS from POINTSLIST\n")); if (!gbPointSizeError) { hWndFocus = GetFocus(); if (hWndFocus != NULL && IsChild(hDlg, hWndFocus) && hWndFocus != GetDlgItem(hDlg, IDCANCEL)) { PreviewUpdate(hDlg, FALSE); } } return TRUE; default: DBGFONTS(("unhandled CBN_%x from POINTSLIST\n",HIWORD(wParam))); break; } break; case IDD_PIXELSLIST: switch (HIWORD(wParam)) { case LBN_SELCHANGE: DBGFONTS(("LBN_SELCHANGE from PIXELSLIST\n")); PreviewUpdate(hDlg, TRUE); return TRUE; default: break; } break; default: break; } break; case WM_NOTIFY: switch (((LPNMHDR)lParam)->code) { case PSN_KILLACTIVE: // // If the TT combo box is visible, update selection // hWndList = GetDlgItem(hDlg, IDD_POINTSLIST); if (hWndList != NULL && IsWindowVisible(hWndList)) { if (!PreviewUpdate(hDlg, FALSE)) { SetDlgMsgResult(hDlg, PSN_KILLACTIVE, TRUE); return TRUE; } SetDlgMsgResult(hDlg, PSN_KILLACTIVE, FALSE); } FontIndex = CurrentFontIndex; if (FontInfo[FontIndex].SizeWant.Y == 0) { // Raster Font, so save actual size gpStateInfo->FontSize = FontInfo[FontIndex].Size; } else { // TT Font, so save desired size gpStateInfo->FontSize = FontInfo[FontIndex].SizeWant; } gpStateInfo->FontWeight = FontInfo[FontIndex].Weight; gpStateInfo->FontFamily = FontInfo[FontIndex].Family; wcscpy(gpStateInfo->FaceName, FontInfo[FontIndex].FaceName); return TRUE; case PSN_APPLY: /* * Write out the state values and exit. */ EndDlgPage(hDlg); return TRUE; } break; /* * For WM_MEASUREITEM and WM_DRAWITEM, since there is only one * owner-draw item (combobox) in the entire dialog box, we don't have * to do a GetDlgItem to figure out who he is. */ case WM_MEASUREITEM: /* * Load the TrueType logo bitmap */ if (hbmTT == NULL) { hbmTT = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_TRUETYPE)); GetObject(hbmTT, sizeof(BITMAP), &bmTT); } /* * Compute the height of face name listbox entries */ if (dyFacelistItem == 0) { HFONT hFont; hDC = GetDC(hDlg); hFont = GetWindowFont(hDlg); if (hFont) { hFont = SelectObject(hDC, hFont); } GetTextMetrics(hDC, &tm); if (hFont) { SelectObject(hDC, hFont); } ReleaseDC(hDlg, hDC); dyFacelistItem = max(tm.tmHeight, bmTT.bmHeight); } ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = dyFacelistItem; return TRUE; case WM_DRAWITEM: DrawItemFontList((LPDRAWITEMSTRUCT)lParam); return TRUE; case WM_DESTROY: /* * Delete the TrueType logo bitmap */ if (hbmTT != NULL) { DeleteObject(hbmTT); hbmTT = NULL; } return TRUE; default: break; } return CommonDlgProc(hDlg, wMsg, wParam, lParam); } int FontListCreate( HWND hDlg, LPTSTR ptszTTFace, BOOL bNewFaceList ) /*++ Initializes the font list by enumerating all fonts and picking the proper ones for our list. Returns FontIndex of selected font (LB_ERR if none) --*/ { TCHAR tszText[80]; LONG lListIndex; ULONG i; HWND hWndShow; // List or Combo box HWND hWndHide; // Combo or List box HWND hWndFaceCombo; HANDLE hStockFont; BOOL bLB; int LastShowX = 0; int LastShowY = 0; int nSameSize = 0; UINT CodePage = gpStateInfo->CodePage; BOOL fDbcsCharSet = IS_ANY_DBCS_CHARSET( CodePageToCharSet( CodePage ) ); BOOL fFindTTFont = FALSE; LPTSTR ptszAltTTFace = NULL; LONG_PTR dwExStyle = 0L; ASSERT(OEMCP != 0); // must be initialized bLB = ((ptszTTFace == NULL) || (ptszTTFace[0] == TEXT('\0'))); if (! bLB) { if (IsAvailableTTFont(ptszTTFace)) { ptszAltTTFace = GetAltFaceName(ptszTTFace); } else { ptszAltTTFace = ptszTTFace; } } DBGFONTS(("FontListCreate %lx, %s, %s new FaceList\n", hDlg, bLB ? "Raster" : "TrueType", bNewFaceList ? "Make" : "No" )); /* * This only enumerates face names if necessary, and * it only enumerates font sizes if necessary */ EnumerateFonts(bLB ? EF_OEMFONT : EF_TTFONT); /* init the TTFaceNames */ DBGFONTS((" Create %s fonts\n", bLB ? "Raster" : "TrueType")); if (bNewFaceList) { PFACENODE panFace; hWndFaceCombo = GetDlgItem(hDlg, IDD_FACENAME); SendMessage(hWndFaceCombo, LB_RESETCONTENT, 0, 0); lListIndex = (LONG)SendMessage(hWndFaceCombo, LB_ADDSTRING, 0, (LPARAM)tszRasterFonts); SendMessage(hWndFaceCombo, LB_SETITEMDATA, lListIndex, TRUE); DBGFONTS(("Added \"%ls\", set Item Data %d = TRUE\n", tszRasterFonts, lListIndex)); for (panFace = gpFaceNames; panFace; panFace = panFace->pNext) { if ((panFace->dwFlag & (EF_TTFONT|EF_NEW)) != (EF_TTFONT|EF_NEW)) { continue; } if (!fDbcsCharSet && (panFace->dwFlag & EF_DBCSFONT)) { continue; } if ((fDbcsCharSet && IsAvailableTTFontCP(panFace->atch, CodePage)) || (!fDbcsCharSet && IsAvailableTTFontCP(panFace->atch, 0))) { if ( !bLB && (_tcscmp(ptszTTFace, panFace->atch) == 0 || _tcscmp(ptszAltTTFace, panFace->atch) == 0) ) { fFindTTFont = TRUE; } lListIndex = (LONG)SendMessage(hWndFaceCombo, LB_ADDSTRING, 0, (LPARAM)panFace->atch); SendMessage(hWndFaceCombo, LB_SETITEMDATA, lListIndex, FALSE); DBGFONTS(("Added \"%ls\", set Item Data %d = FALSE\n", panFace->atch, lListIndex)); } } if (!bLB && !fFindTTFont) { for (panFace = gpFaceNames; panFace; panFace = panFace->pNext) { if ((panFace->dwFlag & (EF_TTFONT|EF_NEW)) != (EF_TTFONT|EF_NEW)) { continue; } if (!fDbcsCharSet && (panFace->dwFlag & EF_DBCSFONT)) { continue; } if (( fDbcsCharSet && IsAvailableTTFontCP(panFace->atch, CodePage)) || (!fDbcsCharSet && IsAvailableTTFontCP(panFace->atch, 0))) { if (_tcscmp(ptszTTFace, panFace->atch) != 0) { _tcscpy(ptszTTFace, panFace->atch); break; } } } } } // if(bNewFaceList) hWndShow = GetDlgItem(hDlg, IDD_BOLDFONT); #if defined(FE_SB) /* * For JAPAN, We uses "MS Gothic" TT font. * So, Bold of this font is not 1:2 width between SBCS:DBCS. */ if (fDbcsCharSet && IsDisableBoldTTFont(ptszTTFace)) { EnableWindow(hWndShow, FALSE); gbBold = FALSE; CheckDlgButton(hDlg, IDD_BOLDFONT, FALSE); } else { #endif CheckDlgButton(hDlg, IDD_BOLDFONT, (bLB || !gbBold) ? FALSE : TRUE); EnableWindow(hWndShow, bLB ? FALSE : TRUE); #if defined(FE_SB) } #endif hWndHide = GetDlgItem(hDlg, bLB ? IDD_POINTSLIST : IDD_PIXELSLIST); ShowWindow(hWndHide, SW_HIDE); EnableWindow(hWndHide, FALSE); hWndShow = GetDlgItem(hDlg, bLB ? IDD_PIXELSLIST : IDD_POINTSLIST); // hStockFont = GetStockObject(SYSTEM_FIXED_FONT); // SendMessage(hWndShow, WM_SETFONT, (DWORD)hStockFont, FALSE); ShowWindow(hWndShow, SW_SHOW); EnableWindow(hWndShow, TRUE); #if defined(FE_SB) if (bNewFaceList) { lcbRESETCONTENT(hWndShow, bLB); } #endif dwExStyle = GetWindowLongPtr(hWndShow, GWL_EXSTYLE); if((dwExStyle & WS_EX_LAYOUTRTL) && !(dwExStyle & WS_EX_RTLREADING)) { // if mirrored RTL Reading means LTR !! SetWindowLongPtr(hWndShow, GWL_EXSTYLE, dwExStyle | WS_EX_RTLREADING); } /* Initialize hWndShow list/combo box */ for (i=0;i 0) { ShowX = FontInfo[i].SizeWant.X; } else { ShowX = FontInfo[i].Size.X; } if (FontInfo[i].SizeWant.Y > 0) { ShowY = FontInfo[i].SizeWant.Y; } else { ShowY = FontInfo[i].Size.Y; } /* * Add the size description string to the end of the right list */ if (TM_IS_TT_FONT(FontInfo[i].Family)) { // point size wsprintf(tszText, TEXT("%2d"), FontInfo[i].SizeWant.Y); } else { // pixel size if ((LastShowX == ShowX) && (LastShowY == ShowY)) { nSameSize++; } else { LastShowX = ShowX; LastShowY = ShowY; nSameSize = 0; } /* * The number nSameSize is appended to the string to distinguish * between Raster fonts of the same size. It is not intended to * be visible and exists off the edge of the list */ if(((dwExStyle & WS_EX_RIGHT) && !(dwExStyle & WS_EX_LAYOUTRTL)) || (!(dwExStyle & WS_EX_RIGHT) && (dwExStyle & WS_EX_LAYOUTRTL))) { // flip it so that the hidden part be at the far left wsprintf(tszText, TEXT("#%d %2d x %2d"), nSameSize, ShowX, ShowY); } else { wsprintf(tszText, TEXT("%2d x %2d #%d"), ShowX, ShowY, nSameSize); } } lListIndex = lcbFINDSTRINGEXACT(hWndShow, bLB, tszText); if (lListIndex == LB_ERR) { lListIndex = lcbADDSTRING(hWndShow, bLB, tszText); } DBGFONTS((" added %ls to %sSLIST(%lx) index %lx\n", tszText, bLB ? "PIXEL" : "POINT", hWndShow, lListIndex)); lcbSETITEMDATA(hWndShow, bLB, (DWORD)lListIndex, i); } /* * Get the FontIndex from the currently selected item. * (i will be LB_ERR if no currently selected item). */ lListIndex = lcbGETCURSEL(hWndShow, bLB); i = lcbGETITEMDATA(hWndShow, bLB, lListIndex); DBGFONTS(("FontListCreate returns 0x%x\n", i)); return i; } /** DrawItemFontList * * Answer the WM_DRAWITEM message sent from the font list box or * facename list box. * * Entry: * lpdis -> DRAWITEMSTRUCT describing object to be drawn * * Returns: * None. * * The object is drawn. */ VOID WINAPI DrawItemFontList(const LPDRAWITEMSTRUCT lpdis) { HDC hDC, hdcMem; DWORD rgbBack, rgbText, rgbFill; TCHAR tszFace[LF_FACESIZE]; HBITMAP hOld; int dy; HBRUSH hbrFill; HWND hWndItem; BOOL bLB; int dxttbmp; if ((int)lpdis->itemID < 0) return; hDC = lpdis->hDC; if (lpdis->itemAction & ODA_FOCUS) { if (lpdis->itemState & ODS_SELECTED) { DrawFocusRect(hDC, &lpdis->rcItem); } } else { if (lpdis->itemState & ODS_SELECTED) { rgbText = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); rgbBack = SetBkColor(hDC, rgbFill = GetSysColor(COLOR_HIGHLIGHT)); } else { rgbText = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); rgbBack = SetBkColor(hDC, rgbFill = GetSysColor(COLOR_WINDOW)); } // draw selection background hbrFill = CreateSolidBrush(rgbFill); if (hbrFill) { FillRect(hDC, &lpdis->rcItem, hbrFill); DeleteObject(hbrFill); } // get the string if (IsWindow(hWndItem = lpdis->hwndItem) == FALSE) { return; } SendMessage(hWndItem, LB_GETTEXT, lpdis->itemID, (LPARAM)tszFace); bLB = (BOOL)SendMessage(hWndItem, LB_GETITEMDATA, lpdis->itemID, 0L); dxttbmp = bLB ? 0 : bmTT.bmWidth; DBGFONTS(("DrawItemFontList must redraw \"%ls\" %s\n", tszFace, bLB ? "Raster" : "TrueType")); // draw the text TabbedTextOut(hDC, lpdis->rcItem.left + dxttbmp, lpdis->rcItem.top, tszFace, _tcslen(tszFace), 0, NULL, dxttbmp); // and the TT bitmap if needed if (!bLB) { hdcMem = CreateCompatibleDC(hDC); if (hdcMem) { hOld = SelectObject(hdcMem, hbmTT); dy = ((lpdis->rcItem.bottom - lpdis->rcItem.top) - bmTT.bmHeight) / 2; BitBlt(hDC, lpdis->rcItem.left, lpdis->rcItem.top + dy, dxttbmp, dyFacelistItem, hdcMem, 0, 0, SRCINVERT); if (hOld) SelectObject(hdcMem, hOld); DeleteDC(hdcMem); } } SetTextColor(hDC, rgbText); SetBkColor(hDC, rgbBack); if (lpdis->itemState & ODS_FOCUS) { DrawFocusRect(hDC, &lpdis->rcItem); } } } UINT GetPointSizeInRange( HWND hDlg, INT Min, INT Max) /*++ Routine Description: Get a size from the Point Size ComboBox edit field Return Value: Point Size - of the edit field limited by Min/Max size 0 - if the field is empty or invalid --*/ { TCHAR szBuf[90]; int nTmp = 0; BOOL bOK; if (GetDlgItemText(hDlg, IDD_POINTSLIST, szBuf, NELEM(szBuf))) { nTmp = GetDlgItemInt(hDlg, IDD_POINTSLIST, &bOK, TRUE); if (bOK && nTmp >= Min && nTmp <= Max) { return nTmp; } } return 0; } /* ----- Preview routines ----- */ LRESULT FontPreviewWndProc( HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam ) /* FontPreviewWndProc * Handles the font preview window */ { PAINTSTRUCT ps; RECT rect; HFONT hfontOld; HBRUSH hbrNew; HBRUSH hbrOld; COLORREF rgbText; COLORREF rgbBk; switch (wMessage) { case WM_ERASEBKGND: break; case WM_PAINT: BeginPaint(hWnd, &ps); /* Draw the font sample */ if (GetWindowLong(hWnd, GWL_ID) == IDD_COLOR_POPUP_COLORS) { rgbText = GetNearestColor(ps.hdc, PopupTextColor(gpStateInfo)); rgbBk = GetNearestColor(ps.hdc, PopupBkColor(gpStateInfo)); } else { rgbText = GetNearestColor(ps.hdc, ScreenTextColor(gpStateInfo)); rgbBk = GetNearestColor(ps.hdc, ScreenBkColor(gpStateInfo)); } SetTextColor(ps.hdc, rgbText); SetBkColor(ps.hdc, rgbBk); GetClientRect(hWnd, &rect); hfontOld = SelectObject(ps.hdc, FontInfo[CurrentFontIndex].hFont); hbrNew = CreateSolidBrush(rgbBk); hbrOld = SelectObject(ps.hdc, hbrNew); PatBlt(ps.hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATCOPY); InflateRect(&rect, -2, -2); DrawText(ps.hdc, g_szPreviewText, -1, &rect, 0); SelectObject(ps.hdc, hbrOld); DeleteObject(hbrNew); SelectObject(ps.hdc, hfontOld); EndPaint(hWnd, &ps); break; default: return DefWindowProc(hWnd, wMessage, wParam, lParam); } return 0L; } /* * Get the font index for a new font * If necessary, attempt to create the font. * Always return a valid FontIndex (even if not correct) * Family: Find/Create a font with of this Family * 0 - don't care * ptszFace: Find/Create a font with this face name. * NULL or TEXT("") - use DefaultFaceName * Size: Must match SizeWant or actual Size. */ int FindCreateFont( DWORD Family, LPTSTR ptszFace, COORD Size, LONG Weight, UINT CodePage) { #define NOT_CREATED_NOR_FOUND -1 #define CREATED_BUT_NOT_FOUND -2 int i; int FontIndex = NOT_CREATED_NOR_FOUND; BOOL bFontOK; TCHAR AltFaceName[LF_FACESIZE]; COORD AltFontSize; BYTE AltFontFamily; ULONG AltFontIndex = 0; LPTSTR ptszAltFace = NULL; BYTE CharSet = CodePageToCharSet(CodePage); ASSERT(OEMCP != 0); DBGFONTS(("FindCreateFont Family=%x %ls (%d,%d) %d %d %x\n", Family, ptszFace, Size.X, Size.Y, Weight, CodePage, CharSet)); if (gfFESystem) { if (IS_ANY_DBCS_CHARSET(CharSet)) { if (ptszFace == NULL || *ptszFace == TEXT('\0')) { ptszFace = DefaultFaceName; } if (Size.Y == 0) { Size = DefaultFontSize; } } else { MakeAltRasterFont(CodePage, &AltFontSize, &AltFontFamily, &AltFontIndex, AltFaceName); if (ptszFace == NULL || *ptszFace == TEXT('\0')) { ptszFace = AltFaceName; } if (Size.Y == 0) { Size.X = AltFontSize.X; Size.Y = AltFontSize.Y; } } } else { if (ptszFace == NULL || *ptszFace == TEXT('\0')) { ptszFace = DefaultFaceName; } if (Size.Y == 0) { Size = DefaultFontSize; } } if (IsAvailableTTFont(ptszFace)) { ptszAltFace = GetAltFaceName(ptszFace); } else { ptszAltFace = ptszFace; } /* * Try to find the exact font */ TryFindExactFont: for (i=0; i < (int)NumberOfFonts; i++) { /* * If looking for a particular Family, skip non-matches */ if ((Family != 0) && ((BYTE)Family != FontInfo[i].Family)) { continue; } /* * Skip non-matching sizes */ if ((!SIZE_EQUAL(FontInfo[i].SizeWant, Size) && !SIZE_EQUAL(FontInfo[i].Size, Size))) { continue; } /* * Skip non-matching weights */ if ((Weight != 0) && (Weight != FontInfo[i].Weight)) { continue; } #if defined(FE_SB) if (!TM_IS_TT_FONT(FontInfo[i].Family) && FontInfo[i].tmCharSet != CharSet) { continue; } #endif /* * Size (and maybe Family) match. * If we don't care about the name, or if it matches, use this font. * Else if name doesn't match and it is a raster font, consider it. */ if ((ptszFace == NULL) || (ptszFace[0] == TEXT('\0')) || (_tcscmp(FontInfo[i].FaceName, ptszFace) == 0) || (_tcscmp(FontInfo[i].FaceName, ptszAltFace) == 0) ) { FontIndex = i; goto FoundFont; } else if (!TM_IS_TT_FONT(FontInfo[i].Family)) { FontIndex = i; } } if (FontIndex == NOT_CREATED_NOR_FOUND) { /* * Didn't find the exact font, so try to create it */ ULONG ulOldEnumFilter; ulOldEnumFilter = SetFontEnumeration(0); SetFontEnumeration(ulOldEnumFilter & ~FE_FILTER_TRUETYPE); if (Size.Y < 0) { Size.Y = -Size.Y; } bFontOK = DoFontEnum(NULL, ptszFace, &Size.Y, 1); SetFontEnumeration(ulOldEnumFilter); if (bFontOK) { DBGFONTS(("FindCreateFont created font!\n")); FontIndex = CREATED_BUT_NOT_FOUND; goto TryFindExactFont; } else { DBGFONTS(("FindCreateFont failed to create font!\n")); } } else if (FontIndex >= 0) { // a close Raster Font fit - only the name doesn't match. goto FoundFont; } /* * Failed to find exact match, even after enumeration, so now try * to find a font of same family and same size or bigger */ for (i=0; i < (int)NumberOfFonts; i++) { #if defined(FE_SB) if (gfFESystem) { if ((Family != 0) && ((BYTE)Family != FontInfo[i].Family)) { continue; } if (!TM_IS_TT_FONT(FontInfo[i].Family) && FontInfo[i].tmCharSet != CharSet) { continue; } } else { #endif if ((BYTE)Family != FontInfo[i].Family) { continue; } #if defined(FE_SB) } #endif if (FontInfo[i].Size.Y >= Size.Y && FontInfo[i].Size.X >= Size.X) { // Same family, size >= desired. FontIndex = i; break; } } if (FontIndex < 0) { DBGFONTS(("FindCreateFont defaults!\n")); #if defined(FE_SB) if (gfFESystem) { if (CodePage == OEMCP) { FontIndex = DefaultFontIndex; } else { FontIndex = AltFontIndex; } } else { #endif FontIndex = DefaultFontIndex; #if defined(FE_SB) } #endif } FoundFont: DBGFONTS(("FindCreateFont returns %x : %ls (%d,%d)\n", FontIndex, FontInfo[FontIndex].FaceName, FontInfo[FontIndex].Size.X, FontInfo[FontIndex].Size.Y)); return FontIndex; #undef NOT_CREATED_NOR_FOUND #undef CREATED_BUT_NOT_FOUND } /* * SelectCurrentSize - Select the right line of the Size listbox/combobox. * bLB : Size controls is a listbox (TRUE for RasterFonts) * FontIndex : Index into FontInfo[] cache * If < 0 then choose a good font. * Returns * FontIndex : Index into FontInfo[] cache */ int SelectCurrentSize(HWND hDlg, BOOL bLB, int FontIndex) { int iCB; HWND hWndList; DBGFONTS(("SelectCurrentSize %lx %s %x\n", hDlg, bLB ? "Raster" : "TrueType", FontIndex)); hWndList = GetDlgItem(hDlg, bLB ? IDD_PIXELSLIST : IDD_POINTSLIST); iCB = lcbGETCOUNT(hWndList, bLB); DBGFONTS((" Count of items in %lx = %lx\n", hWndList, iCB)); if (FontIndex >= 0) { /* * look for FontIndex */ while (iCB > 0) { iCB--; if (lcbGETITEMDATA(hWndList, bLB, iCB) == FontIndex) { lcbSETCURSEL(hWndList, bLB, iCB); break; } } } else { /* * look for a reasonable default size: looking backwards, find * the first one same height or smaller. */ DWORD Size; Size = GetWindowLong(hDlg, GWLP_USERDATA); #if defined(FE_SB) ASSERT(OEMCP != 0); if (gfFESystem && bLB && (FontInfo[CurrentFontIndex].tmCharSet != LOBYTE(LOWORD(Size))) ) { TCHAR AltFaceName[LF_FACESIZE]; COORD AltFontSize; BYTE AltFontFamily; ULONG AltFontIndex = 0; MakeAltRasterFont(gpStateInfo->CodePage, &AltFontSize, &AltFontFamily, &AltFontIndex, AltFaceName); while (iCB > 0) { iCB--; if (lcbGETITEMDATA(hWndList, bLB, iCB) == (int)AltFontIndex) { lcbSETCURSEL(hWndList, bLB, iCB); break; } } } else #endif while (iCB > 0) { iCB--; FontIndex = lcbGETITEMDATA(hWndList, bLB, iCB); if (FontInfo[FontIndex].Size.Y <= HIWORD(Size)) { lcbSETCURSEL(hWndList, bLB, iCB); break; } } } DBGFONTS(("SelectCurrentSize returns %x\n", FontIndex)); return FontIndex; } BOOL SelectCurrentFont(HWND hDlg, int FontIndex) { BOOL bLB; DBGFONTS(("SelectCurrentFont hDlg=%lx, FontIndex=%x\n", hDlg, FontIndex)); bLB = !TM_IS_TT_FONT(FontInfo[FontIndex].Family); SendDlgItemMessage(hDlg, IDD_FACENAME, LB_SELECTSTRING, (WPARAM)-1, bLB ? (LPARAM)tszRasterFonts : (LPARAM)FontInfo[FontIndex].FaceName); SelectCurrentSize(hDlg, bLB, FontIndex); return bLB; } BOOL PreviewInit( HWND hDlg ) /* PreviewInit * Prepares the preview code, sizing the window and the dialog to * make an attractive preview. * Returns TRUE if Raster Fonts, FALSE if TT Font */ { int nFont; DBGFONTS(("PreviewInit hDlg=%lx\n", hDlg)); /* * Set the current font */ nFont = FindCreateFont(gpStateInfo->FontFamily, gpStateInfo->FaceName, gpStateInfo->FontSize, gpStateInfo->FontWeight, gpStateInfo->CodePage); DBGPRINT(("Changing Font Number from %d to %d\n", CurrentFontIndex, nFont)); CurrentFontIndex = nFont; return SelectCurrentFont(hDlg, nFont); } BOOL PreviewUpdate( HWND hDlg, BOOL bLB ) /*++ Does the preview of the selected font. --*/ { PFONT_INFO lpFont; int FontIndex; LONG lIndex; HWND hWnd; TCHAR tszText[60]; TCHAR tszFace[LF_FACESIZE + CCH_SELECTEDFONT]; HWND hWndList; DBGFONTS(("PreviewUpdate hDlg=%lx, %s\n", hDlg, bLB ? "Raster" : "TrueType")); hWndList = GetDlgItem(hDlg, bLB ? IDD_PIXELSLIST : IDD_POINTSLIST); /* When we select a font, we do the font preview by setting it into * the appropriate list box */ lIndex = lcbGETCURSEL(hWndList, bLB); DBGFONTS(("PreviewUpdate GETCURSEL gets %x\n", lIndex)); if ((lIndex < 0) && !bLB) { COORD NewSize; lIndex = (LONG)SendDlgItemMessage(hDlg, IDD_FACENAME, LB_GETCURSEL, 0, 0L); SendDlgItemMessage(hDlg, IDD_FACENAME, LB_GETTEXT, lIndex, (LPARAM)tszFace); NewSize.X = 0; NewSize.Y = (SHORT)GetPointSizeInRange(hDlg, MIN_PIXEL_HEIGHT, MAX_PIXEL_HEIGHT); if (NewSize.Y == 0) { TCHAR tszBuf[60]; /* * Use tszText, tszBuf to put up an error msg for bad point size */ gbPointSizeError = TRUE; LoadString(ghInstance, IDS_FONTSIZE, tszBuf, NELEM(tszBuf)); wsprintf(tszText, tszBuf, MIN_PIXEL_HEIGHT, MAX_PIXEL_HEIGHT); GetWindowText(hDlg, tszBuf, NELEM(tszBuf)); MessageBoxEx(hDlg, tszText, tszBuf, MB_OK|MB_ICONINFORMATION, 0L); SetFocus(hWndList); gbPointSizeError = FALSE; return FALSE; } FontIndex = FindCreateFont(FF_MODERN|TMPF_VECTOR|TMPF_TRUETYPE, tszFace, NewSize, 0, gpStateInfo->CodePage); } else { FontIndex = lcbGETITEMDATA(hWndList, bLB, lIndex); } if (FontIndex < 0) { FontIndex = DefaultFontIndex; } /* * If we've selected a new font, tell the property sheet we've changed */ if (CurrentFontIndex != (ULONG)FontIndex) { CurrentFontIndex = FontIndex; } lpFont = &FontInfo[FontIndex]; /* Display the new font */ _tcscpy(tszFace, tszSelectedFont); _tcscat(tszFace, lpFont->FaceName); SetDlgItemText(hDlg, IDD_GROUP, tszFace); /* Put the font size in the static boxes */ wsprintf(tszText, TEXT("%u"), lpFont->Size.X); hWnd = GetDlgItem(hDlg, IDD_FONTWIDTH); SetWindowText(hWnd, tszText); InvalidateRect(hWnd, NULL, TRUE); wsprintf(tszText, TEXT("%u"), lpFont->Size.Y); hWnd = GetDlgItem(hDlg, IDD_FONTHEIGHT); SetWindowText(hWnd, tszText); InvalidateRect(hWnd, NULL, TRUE); /* Force the preview windows to repaint */ hWnd = GetDlgItem(hDlg, IDD_PREVIEWWINDOW); SendMessage(hWnd, CM_PREVIEW_UPDATE, 0, 0); hWnd = GetDlgItem(hDlg, IDD_FONTWINDOW); InvalidateRect(hWnd, NULL, TRUE); DBGFONTS(("Font %x, (%d,%d) %ls\n", FontIndex, FontInfo[FontIndex].Size.X, FontInfo[FontIndex].Size.Y, FontInfo[FontIndex].FaceName)); return TRUE; }