2 * fontview display class
6 * Copyright (C) 2007 Timo Kreuzer <timo <dot> kreuzer <at> reactos <dot> org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 extern INT g_NumFonts
;
32 extern WCHAR g_FontTitle
[];
34 const WCHAR g_szFontDisplayClassName
[] = L
"FontDisplayClass";
35 LRESULT CALLBACK
DisplayProc(HWND
, UINT
, WPARAM
, LPARAM
);
37 /* Internal data storage type */
41 WCHAR szTypeFaceName
[LF_FULLFACESIZE
];
42 WCHAR szFormat
[MAX_FORMAT
];
43 WCHAR szString
[MAX_STRING
];
48 HFONT hFonts
[MAX_SIZES
];
49 int nSizes
[MAX_SIZES
];
50 int nHeights
[MAX_SIZES
];
53 /* This is the only public function, it registers the class */
55 Display_InitClass(HINSTANCE hInstance
)
59 /* Set the fontdisplay window class structure */
60 wincl
.cbSize
= sizeof(WNDCLASSEX
);
61 wincl
.style
= CS_DBLCLKS
;
62 wincl
.lpfnWndProc
= DisplayProc
;
65 wincl
.hInstance
= hInstance
;
67 wincl
.hCursor
= LoadCursor (NULL
, IDC_ARROW
);
68 wincl
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
69 wincl
.lpszMenuName
= NULL
;
70 wincl
.lpszClassName
= g_szFontDisplayClassName
;
73 /* Register the window class, and if it fails return FALSE */
74 if (!RegisterClassExW (&wincl
))
82 Display_DrawText(HDC hDC
, DISPLAYDATA
* pData
, int nYPos
)
88 WCHAR szCaption
[LF_FULLFACESIZE
+ 20];
90 /* This is the location on the DC where we draw */
93 hOldFont
= SelectObject(hDC
, pData
->hCaptionFont
);
94 GetTextMetrics(hDC
, &tm
);
96 swprintf(szCaption
, L
"%s%s", pData
->szTypeFaceName
, pData
->szFormat
);
97 TextOutW(hDC
, 0, y
, szCaption
, (INT
)wcslen(szCaption
));
98 y
+= tm
.tmHeight
+ SPACING1
;
100 /* Draw a separation Line */
101 SelectObject(hDC
, GetStockObject(BLACK_PEN
));
102 MoveToEx(hDC
, 0, y
, NULL
);
103 LineTo(hDC
, 10000, y
);
106 /* TODO: Output font info */
108 /* Output Character set */
109 SelectObject(hDC
, pData
->hCharSetFont
);
110 GetTextMetrics(hDC
, &tm
);
111 swprintf(szCaption
, L
"abcdefghijklmnopqrstuvwxyz");
112 TextOutW(hDC
, 0, y
, szCaption
, (INT
)wcslen(szCaption
));
113 y
+= tm
.tmHeight
+ 1;
115 swprintf(szCaption
, L
"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
116 TextOutW(hDC
, 0, y
, szCaption
, (INT
)wcslen(szCaption
));
117 y
+= tm
.tmHeight
+ 1;
119 swprintf(szCaption
, L
"0123456789.:,;(\"~!@#$%%^&*')");
120 TextOutW(hDC
, 0, y
, szCaption
, (INT
)wcslen(szCaption
));
121 y
+= tm
.tmHeight
+ 1;
123 /* Draw a separation Line */
124 SelectObject(hDC
, GetStockObject(BLACK_PEN
));
125 MoveToEx(hDC
, 0, y
, NULL
);
126 LineTo(hDC
, 10000, y
);
129 /* Output the strings for different sizes */
130 for (i
= 0; i
< MAX_SIZES
; i
++)
132 SelectObject(hDC
, pData
->hFonts
[i
]);
133 TextOutW(hDC
, 20, y
, pData
->szString
, (INT
)wcslen(pData
->szString
));
134 GetTextMetrics(hDC
, &tm
);
135 y
+= tm
.tmHeight
+ 1;
136 SelectObject(hDC
, pData
->hSizeFont
);
137 swprintf(szSize
, L
"%d", pData
->nSizes
[i
]);
138 TextOutW(hDC
, 0, y
- 13 - tm
.tmDescent
, szSize
, (INT
)wcslen(szSize
));
140 SelectObject(hDC
, hOldFont
);
148 const LOGFONTW
*lpelfe
,
149 const TEXTMETRICW
*lptm
,
153 PNEWTEXTMETRICW pntmw
= (PNEWTEXTMETRICW
)lptm
;
154 PBOOL pfOpenType
= (PBOOL
)lParam
;
156 if (FontType
& TRUETYPE_FONTTYPE
)
158 if (pntmw
->ntmFlags
& (NTM_TT_OPENTYPE
| NTM_PS_OPENTYPE
))
168 Display_SetTypeFace(HWND hwnd
, PLOGFONTW pLogFont
)
179 LPOUTLINETEXTMETRICW pOTM
= (LPOUTLINETEXTMETRICW
)Buffer
;
182 /* Set the new type face name */
183 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
184 lstrcpynW(pData
->szTypeFaceName
, pLogFont
->lfFaceName
,
185 ARRAYSIZE(pData
->szTypeFaceName
));
187 /* Create the new fonts */
189 DeleteObject(pData
->hCharSetFont
);
192 logfont
.lfHeight
= -MulDiv(16, GetDeviceCaps(GetDC(NULL
), LOGPIXELSY
), 72);
193 pData
->hCharSetFont
= CreateFontIndirectW(&logfont
);
195 /* Get font format */
196 SelectObject(hDC
, pData
->hCharSetFont
);
197 GetTextMetrics(hDC
, &tm
);
198 if (tm
.tmPitchAndFamily
& TMPF_TRUETYPE
)
200 if (GetOutlineTextMetricsW(hDC
, sizeof(Buffer
), pOTM
))
203 pb
+= (WORD
)(DWORD_PTR
)pOTM
->otmpStyleName
;
207 lstrcatW(pData
->szTypeFaceName
, L
" ");
208 lstrcatW(pData
->szTypeFaceName
, pch
);
213 EnumFontFamiliesExW(hDC
, &logfont
,
214 EnumFontFamProcW
, (LPARAM
)&fOpenType
, 0);
217 swprintf(pData
->szFormat
, L
" (OpenType)");
219 swprintf(pData
->szFormat
, L
" (TrueType)");
221 else if (tm
.tmPitchAndFamily
& TMPF_VECTOR
)
223 swprintf(pData
->szFormat
, L
" (Vector)");
227 swprintf(pData
->szFormat
, L
" (Raster)");
230 for (i
= 0; i
< MAX_SIZES
; i
++)
232 DeleteObject(pData
->hFonts
[i
]);
233 logfont
.lfHeight
= -MulDiv(pData
->nSizes
[i
], GetDeviceCaps(hDC
, LOGPIXELSY
), 72);
234 pData
->hFonts
[i
] = CreateFontIndirectW(&logfont
);
237 /* Calculate new page dimensions */
238 pData
->nPageHeight
= Display_DrawText(hDC
, pData
, 0);
239 ReleaseDC(hwnd
, hDC
);
241 /* Set the vertical scrolling range and page size */
242 GetClientRect(hwnd
, &rect
);
243 si
.cbSize
= sizeof(si
);
244 si
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
| SIF_TRACKPOS
;
246 si
.nMax
= pData
->nPageHeight
;
247 si
.nPage
= rect
.bottom
;
250 SetScrollInfo(hwnd
, SB_VERT
, &si
, TRUE
);
256 Display_SetString(HWND hwnd
, LPCWSTR pszString
)
260 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
261 lstrcpynW(pData
->szString
, pszString
, ARRAYSIZE(pData
->szString
));
263 InvalidateRect(hwnd
, NULL
, TRUE
);
269 Display_OnCreate(HWND hwnd
)
272 const int nSizes
[MAX_SIZES
] = {8, 12, 18, 24, 36, 48, 60, 72};
274 LOGFONTW LogFont
= {50, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
,
275 ANSI_CHARSET
, OUT_DEFAULT_PRECIS
,
276 CLIP_DEFAULT_PRECIS
, PROOF_QUALITY
,
277 DEFAULT_PITCH
, L
"MS Shell Dlg"};
279 /* Create data structure */
280 pData
= malloc(sizeof(DISPLAYDATA
));
281 ZeroMemory(pData
, sizeof(DISPLAYDATA
));
283 /* Set the window's GWLP_USERDATA to our data structure */
284 SetWindowLongPtr(hwnd
, GWLP_USERDATA
, (LONG_PTR
)pData
);
286 for (i
= 0; i
< MAX_SIZES
; i
++)
288 pData
->nSizes
[i
] = nSizes
[i
];
291 pData
->hCaptionFont
= CreateFontIndirectW(&LogFont
);
292 LogFont
.lfHeight
= 12;
293 pData
->hSizeFont
= CreateFontIndirectW(&LogFont
);
295 Display_SetString(hwnd
,
296 L
"Jackdaws love my big sphinx of quartz. 1234567890");
298 Display_SetTypeFace(hwnd
, &LogFont
);
304 Display_OnPaint(HWND hwnd
)
310 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
312 /* Get the Scroll position */
313 si
.cbSize
= sizeof(si
);
315 GetScrollInfo(hwnd
, SB_VERT
, &si
);
317 BeginPaint(hwnd
, &ps
);
319 /* Erase background */
320 FillRect(ps
.hdc
, &ps
.rcPaint
, GetStockObject(WHITE_BRUSH
));
323 Display_DrawText(ps
.hdc
, pData
, si
.nPos
);
331 Display_OnSize(HWND hwnd
)
337 GetClientRect(hwnd
, &rect
);
339 /* Get the old scroll pos */
340 si
.cbSize
= sizeof(si
);
342 GetScrollInfo(hwnd
, SB_VERT
, &si
);
345 /* Set the new page size */
347 si
.nPage
= rect
.bottom
;
348 SetScrollInfo(hwnd
, SB_VERT
, &si
, TRUE
);
350 /* Get the new scroll pos */
352 GetScrollInfo(hwnd
, SB_VERT
, &si
);
354 /* If they don't match ... */
355 if (nOldPos
!= si
.nPos
)
357 /* ... scroll the window */
358 ScrollWindowEx(hwnd
, 0, nOldPos
- si
.nPos
, NULL
, NULL
, NULL
, NULL
, SW_INVALIDATE
);
366 Display_OnVScroll(HWND hwnd
, WPARAM wParam
)
371 si
.cbSize
= sizeof(si
);
372 si
.fMask
= SIF_POS
| SIF_RANGE
| SIF_TRACKPOS
;
373 GetScrollInfo(hwnd
, SB_VERT
, &si
);
375 switch(LOWORD(wParam
))
390 case SB_THUMBPOSITION
:
397 nPos
= max(nPos
, si
.nMin
);
398 nPos
= min(nPos
, si
.nMax
);
401 ScrollWindowEx(hwnd
, 0, si
.nPos
- nPos
, NULL
, NULL
, NULL
, NULL
, SW_INVALIDATE
);
402 si
.cbSize
= sizeof(si
);
405 SetScrollInfo(hwnd
, SB_VERT
, &si
, TRUE
);
413 Display_OnDestroy(HWND hwnd
)
418 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
420 /* Delete the fonts */
421 DeleteObject(pData
->hCaptionFont
);
422 DeleteObject(pData
->hCharSetFont
);
423 DeleteObject(pData
->hSizeFont
);
425 for (i
= 0; i
< MAX_SIZES
; i
++)
427 DeleteObject(pData
->hFonts
[i
]);
430 /* Free the data structure */
437 Display_OnPrint(HWND hwnd
)
443 /* Clears the memory before using it */
444 ZeroMemory(&pfont
, sizeof(pfont
));
446 pfont
.lStructSize
= sizeof(pfont
);
447 pfont
.hwndOwner
= hwnd
;
448 pfont
.hDevMode
= NULL
;
449 pfont
.hDevNames
= NULL
;
450 pfont
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
452 pfont
.nFromPage
= 0xFFFF;
453 pfont
.nToPage
= 0xFFFF;
455 pfont
.nMaxPage
= 0xFFFF;
457 /* Opens up the print dialog box */
458 if (PrintDlg(&pfont
))
464 pData
= malloc(sizeof(DISPLAYDATA
));
465 ZeroMemory(pData
, sizeof(DISPLAYDATA
));
467 /* Sets up the font layout */
468 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
470 docinfo
.cbSize
= sizeof(DOCINFO
);
471 docinfo
.lpszDocName
= L
"Printing Font";
472 docinfo
.lpszOutput
= NULL
;
473 docinfo
.lpszDatatype
= NULL
;
476 /* We start printing */
477 StartDoc(pfont
.hDC
, &docinfo
);
479 /* Grabs the text metrics for the printer */
480 GetTextMetrics(pfont
.hDC
, &tm
);
482 /* Start out with 0 for the y position for the page */
485 /* Starts out with the current page */
486 StartPage(pfont
.hDC
);
488 /* Used when printing for more than one copy */
489 for (copies
= 0; copies
< pfont
.nCopies
; copies
++)
492 TextOutW(pfont
.hDC
, 10, yPos
, L
"Testing...1...2...3", 19);
494 /* TODO: Determine if using Display_DrawText() will work for both rendering out to the
495 window and to the printer output */
497 Display_DrawText(pfont
.hDC
, pData
, yPos
);
500 /* Ends the current page */
503 /* If we are making more than one copy, start a new page */
504 if (copies
!= pfont
.nCopies
)
507 StartPage(pfont
.hDC
);
511 /* The printing is now over */
516 /* Frees the memory since we no longer need it for now */
525 Display_GetFullName(HWND hwnd
, INT length
, PWSTR ptr
)
530 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
532 len
= wcslen(pData
->szTypeFaceName
) + wcslen(pData
->szFormat
) + 2;
534 if (ptr
!= NULL
&& length
>= len
)
536 swprintf(ptr
, L
"%s%s", pData
->szTypeFaceName
, pData
->szFormat
);
543 DisplayProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
548 return Display_OnCreate(hwnd
);
551 return Display_OnPaint(hwnd
);
554 return Display_OnSize(hwnd
);
557 return Display_OnVScroll(hwnd
, wParam
);
559 case FVM_SETTYPEFACE
:
560 return Display_SetTypeFace(hwnd
, (PLOGFONTW
)lParam
);
563 return Display_SetString(hwnd
, (WCHAR
*)lParam
);
565 case FVM_GETFULLNAME
:
566 return Display_GetFullName(hwnd
, (INT
)wParam
, (PWSTR
)lParam
);
569 return Display_OnDestroy(hwnd
);
572 return DefWindowProcW(hwnd
, message
, wParam
, lParam
);