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.
28 const WCHAR g_szFontDisplayClassName
[] = L
"FontDisplayClass";
29 LRESULT CALLBACK
DisplayProc(HWND
, UINT
, WPARAM
, LPARAM
);
31 /* Internal data storage type */
35 WCHAR szTypeFaceName
[LF_FULLFACESIZE
];
36 WCHAR szFormat
[MAX_FORMAT
];
37 WCHAR szString
[MAX_STRING
];
42 HFONT hFonts
[MAX_SIZES
];
43 int nSizes
[MAX_SIZES
];
44 int nHeights
[MAX_SIZES
];
47 /* This is the only public function, it registers the class */
49 Display_InitClass(HINSTANCE hInstance
)
53 /* Set the fontdisplay window class structure */
54 wincl
.cbSize
= sizeof(WNDCLASSEX
);
55 wincl
.style
= CS_DBLCLKS
;
56 wincl
.lpfnWndProc
= DisplayProc
;
59 wincl
.hInstance
= hInstance
;
61 wincl
.hCursor
= LoadCursor (NULL
, IDC_ARROW
);
62 wincl
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
63 wincl
.lpszMenuName
= NULL
;
64 wincl
.lpszClassName
= g_szFontDisplayClassName
;
67 /* Register the window class, and if it fails return FALSE */
68 if (!RegisterClassExW (&wincl
))
76 Display_DrawText(HDC hDC
, DISPLAYDATA
* pData
, int nYPos
)
82 WCHAR szCaption
[LF_FULLFACESIZE
+ 20];
84 /* This is the location on the DC where we draw */
87 hOldFont
= SelectObject(hDC
, pData
->hCaptionFont
);
88 GetTextMetrics(hDC
, &tm
);
90 swprintf(szCaption
, L
"%s%s", pData
->szTypeFaceName
, pData
->szFormat
);
91 TextOutW(hDC
, 0, y
, szCaption
, (INT
)wcslen(szCaption
));
92 y
+= tm
.tmHeight
+ SPACING1
;
94 /* Draw a seperation Line */
95 SelectObject(hDC
, GetStockObject(BLACK_PEN
));
96 MoveToEx(hDC
, 0, y
, NULL
);
97 LineTo(hDC
, 10000, y
);
100 /* TODO: Output font info */
102 /* Output Character set */
103 SelectObject(hDC
, pData
->hCharSetFont
);
104 GetTextMetrics(hDC
, &tm
);
105 swprintf(szCaption
, L
"abcdefghijklmnopqrstuvwxyz");
106 TextOutW(hDC
, 0, y
, szCaption
, (INT
)wcslen(szCaption
));
107 y
+= tm
.tmHeight
+ 1;
109 swprintf(szCaption
, L
"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
110 TextOutW(hDC
, 0, y
, szCaption
, (INT
)wcslen(szCaption
));
111 y
+= tm
.tmHeight
+ 1;
113 swprintf(szCaption
, L
"0123456789.:,;(\"~!@#$%^&*')");
114 TextOutW(hDC
, 0, y
, szCaption
, (INT
)wcslen(szCaption
));
115 y
+= tm
.tmHeight
+ 1;
117 /* Draw a seperation Line */
118 SelectObject(hDC
, GetStockObject(BLACK_PEN
));
119 MoveToEx(hDC
, 0, y
, NULL
);
120 LineTo(hDC
, 10000, y
);
123 /* Output the strings for different sizes */
124 for (i
= 0; i
< MAX_SIZES
; i
++)
126 SelectObject(hDC
, pData
->hFonts
[i
]);
127 TextOutW(hDC
, 20, y
, pData
->szString
, (INT
)wcslen(pData
->szString
));
128 GetTextMetrics(hDC
, &tm
);
129 y
+= tm
.tmHeight
+ 1;
130 SelectObject(hDC
, pData
->hSizeFont
);
131 swprintf(szSize
, L
"%d", pData
->nSizes
[i
]);
132 TextOutW(hDC
, 0, y
- 13 - tm
.tmDescent
, szSize
, (INT
)wcslen(szSize
));
134 SelectObject(hDC
, hOldFont
);
142 const LOGFONTW
*lpelfe
,
143 const TEXTMETRICW
*lptm
,
147 PNEWTEXTMETRICW pntmw
= (PNEWTEXTMETRICW
)lptm
;
148 PBOOL pfOpenType
= (PBOOL
)lParam
;
150 if (FontType
& TRUETYPE_FONTTYPE
)
152 if (pntmw
->ntmFlags
& (NTM_TT_OPENTYPE
| NTM_PS_OPENTYPE
))
162 Display_SetTypeFace(HWND hwnd
, PEXTLOGFONTW pExtLogFont
)
172 /* Set the new type face name */
173 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
174 _snwprintf(pData
->szTypeFaceName
, LF_FULLFACESIZE
, pExtLogFont
->elfFullName
);
176 /* Create the new fonts */
178 DeleteObject(pData
->hCharSetFont
);
180 logfont
= pExtLogFont
->elfLogFont
;
181 logfont
.lfHeight
= -MulDiv(16, GetDeviceCaps(GetDC(NULL
), LOGPIXELSY
), 72);
182 pData
->hCharSetFont
= CreateFontIndirectW(&logfont
);
184 /* Get font format */
185 SelectObject(hDC
, pData
->hCharSetFont
);
186 GetTextMetrics(hDC
, &tm
);
187 if (tm
.tmPitchAndFamily
& TMPF_TRUETYPE
)
189 BOOL fOpenType
= FALSE
;
191 EnumFontFamiliesExW(hDC
, &logfont
,
192 EnumFontFamProcW
, (LPARAM
)&fOpenType
, 0);
195 swprintf(pData
->szFormat
, L
" (OpenType)");
197 swprintf(pData
->szFormat
, L
" (TrueType)");
199 else if (tm
.tmPitchAndFamily
& TMPF_VECTOR
)
201 swprintf(pData
->szFormat
, L
" (Vector)");
205 swprintf(pData
->szFormat
, L
" (Raster)");
208 for (i
= 0; i
< MAX_SIZES
; i
++)
210 DeleteObject(pData
->hFonts
[i
]);
211 logfont
.lfHeight
= -MulDiv(pData
->nSizes
[i
], GetDeviceCaps(hDC
, LOGPIXELSY
), 72);
212 pData
->hFonts
[i
] = CreateFontIndirectW(&logfont
);
215 /* Calculate new page dimensions */
216 pData
->nPageHeight
= Display_DrawText(hDC
, pData
, 0);
217 ReleaseDC(hwnd
, hDC
);
219 /* Set the vertical scrolling range and page size */
220 GetClientRect(hwnd
, &rect
);
221 si
.cbSize
= sizeof(si
);
222 si
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
| SIF_TRACKPOS
;
224 si
.nMax
= pData
->nPageHeight
;
225 si
.nPage
= rect
.bottom
;
228 SetScrollInfo(hwnd
, SB_VERT
, &si
, TRUE
);
234 Display_SetString(HWND hwnd
, LPARAM lParam
)
238 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
239 _snwprintf(pData
->szString
, MAX_STRING
, (WCHAR
*)lParam
);
241 InvalidateRect(hwnd
, NULL
, TRUE
);
247 Display_OnCreate(HWND hwnd
)
250 const int nSizes
[MAX_SIZES
] = {8, 12, 18, 24, 36, 48, 60, 72};
252 EXTLOGFONTW ExtLogFont
= {{50, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
,
253 ANSI_CHARSET
, OUT_DEFAULT_PRECIS
,
254 CLIP_DEFAULT_PRECIS
, PROOF_QUALITY
,
255 DEFAULT_PITCH
, L
"Ms Shell Dlg"},
258 /* Create data structure */
259 pData
= malloc(sizeof(DISPLAYDATA
));
260 ZeroMemory(pData
, sizeof(DISPLAYDATA
));
262 /* Set the window's GWLP_USERDATA to our data structure */
263 SetWindowLongPtr(hwnd
, GWLP_USERDATA
, (LONG_PTR
)pData
);
265 for (i
= 0; i
< MAX_SIZES
; i
++)
267 pData
->nSizes
[i
] = nSizes
[i
];
270 pData
->hCaptionFont
= CreateFontIndirectW(&ExtLogFont
.elfLogFont
);
271 ExtLogFont
.elfLogFont
.lfHeight
= 12;
272 pData
->hSizeFont
= CreateFontIndirectW(&ExtLogFont
.elfLogFont
);
274 Display_SetString(hwnd
, (LPARAM
)L
"Jackdaws love my big sphinx of quartz. 1234567890");
276 Display_SetTypeFace(hwnd
, &ExtLogFont
);
282 Display_OnPaint(HWND hwnd
)
288 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
290 /* Get the Scroll position */
291 si
.cbSize
= sizeof(si
);
293 GetScrollInfo(hwnd
, SB_VERT
, &si
);
295 BeginPaint(hwnd
, &ps
);
297 /* Erase background */
298 FillRect(ps
.hdc
, &ps
.rcPaint
, GetStockObject(WHITE_BRUSH
));
301 Display_DrawText(ps
.hdc
, pData
, si
.nPos
);
309 Display_OnSize(HWND hwnd
)
315 GetClientRect(hwnd
, &rect
);
317 /* Get the old scroll pos */
318 si
.cbSize
= sizeof(si
);
320 GetScrollInfo(hwnd
, SB_VERT
, &si
);
323 /* Set the new page size */
325 si
.nPage
= rect
.bottom
;
326 SetScrollInfo(hwnd
, SB_VERT
, &si
, TRUE
);
328 /* Get the new scroll pos */
330 GetScrollInfo(hwnd
, SB_VERT
, &si
);
332 /* If they don't match ... */
333 if (nOldPos
!= si
.nPos
)
335 /* ... scroll the window */
336 ScrollWindowEx(hwnd
, 0, nOldPos
- si
.nPos
, NULL
, NULL
, NULL
, NULL
, SW_INVALIDATE
);
344 Display_OnVScroll(HWND hwnd
, WPARAM wParam
)
349 si
.cbSize
= sizeof(si
);
350 si
.fMask
= SIF_POS
| SIF_RANGE
| SIF_TRACKPOS
;
351 GetScrollInfo(hwnd
, SB_VERT
, &si
);
353 switch(LOWORD(wParam
))
368 case SB_THUMBPOSITION
:
375 nPos
= max(nPos
, si
.nMin
);
376 nPos
= min(nPos
, si
.nMax
);
379 ScrollWindowEx(hwnd
, 0, si
.nPos
- nPos
, NULL
, NULL
, NULL
, NULL
, SW_INVALIDATE
);
380 si
.cbSize
= sizeof(si
);
383 SetScrollInfo(hwnd
, SB_VERT
, &si
, TRUE
);
391 Display_OnDestroy(HWND hwnd
)
396 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
398 /* Delete the fonts */
399 DeleteObject(pData
->hCaptionFont
);
400 DeleteObject(pData
->hCharSetFont
);
401 DeleteObject(pData
->hSizeFont
);
403 for (i
= 0; i
< MAX_SIZES
; i
++)
405 DeleteObject(pData
->hFonts
[i
]);
408 /* Free the data structure */
415 Display_OnPrint(HWND hwnd
)
422 pData
= malloc(sizeof(DISPLAYDATA
));
423 ZeroMemory(pData
, sizeof(DISPLAYDATA
));
425 /* Sets up the font layout */
426 pData
= (DISPLAYDATA
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
428 /* Clears the memory before using it */
429 ZeroMemory(&pfont
, sizeof(pfont
));
431 pfont
.lStructSize
= sizeof(pfont
);
432 pfont
.hwndOwner
= hwnd
;
433 pfont
.hDevMode
= NULL
;
434 pfont
.hDevNames
= NULL
;
435 pfont
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
437 pfont
.nFromPage
= 0xFFFF;
438 pfont
.nToPage
= 0xFFFF;
440 pfont
.nMaxPage
= 0xFFFF;
442 /* Opens up the print dialog box */
443 if (PrintDlg(&pfont
))
447 docinfo
.cbSize
= sizeof(DOCINFO
);
448 docinfo
.lpszDocName
= "Printing Font";
449 docinfo
.lpszOutput
= NULL
;
450 docinfo
.lpszDatatype
= NULL
;
453 /* We start printing */
454 StartDoc(pfont
.hDC
, &docinfo
);
456 /* Grabs the text metrics for the printer */
457 GetTextMetrics(pfont
.hDC
, &tm
);
459 /* Start out with 0 for the y position for the page */
462 /* Starts out with the current page */
463 StartPage(pfont
.hDC
);
465 /* Used when printing for more than one copy */
466 for (copies
= 0; copies
< pfont
.nCopies
; copies
++)
469 TextOutW(pfont
.hDC
, 10, yPos
, L
"Testing...1...2...3", 19);
471 /* TODO: Determine if using Display_DrawText() will work for both rendering out to the
472 window and to the printer output */
473 //Display_DrawText(pfont.hDC, pData, yPos);
475 /* Ends the current page */
478 /* If we are making more than one copy, start a new page */
479 if (copies
!= pfont
.nCopies
)
482 StartPage(pfont
.hDC
);
486 /* The printing is now over */
494 /* Frees the memory since we no longer need it for now */
501 DisplayProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
506 return Display_OnCreate(hwnd
);
509 return Display_OnPaint(hwnd
);
512 return Display_OnSize(hwnd
);
515 return Display_OnVScroll(hwnd
, wParam
);
517 case FVM_SETTYPEFACE
:
518 return Display_SetTypeFace(hwnd
, (PEXTLOGFONTW
)lParam
);
521 return Display_SetString(hwnd
, lParam
);
524 return Display_OnDestroy(hwnd
);
527 return DefWindowProcW(hwnd
, message
, wParam
, lParam
);