1 /*
2 * COMMDLG - Font Dialog
3 *
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include <ctype.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnls.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "commdlg.h"
33 #include "dlgs.h"
34 #include "wine/debug.h"
35 #include "cderr.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
38
39 static const WCHAR strWineFontData[] = {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A',0};
40 static const WCHAR strWineFontData_a[] =
41 {'_','_','W','I','N','E','_','F','O','N','T','D','L','G','D','A','T','A','_','A',0};
42 static const WCHAR chooseFontW[] = {'C','H','O','O','S','E','_','F','O','N','T',0};
43
44 #include "cdlg.h"
45
46 /* image list with TrueType bitmaps and more */
47 static HIMAGELIST himlTT = 0;
48 #define TTBITMAP_XSIZE 20 /* x-size of the bitmaps */
49
50 static INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
51 static INT_PTR CALLBACK FormatCharDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
52
53 /* There is a table here of all charsets, and the sample text for each.
54 * There is a second table that translates a charset into an index into
55 * the first table.
56 */
57
58 #define CI(cs) ((IDS_CHARSET_##cs)-IDS_CHARSET_ANSI)
59
60
61 static const WCHAR stWestern[]={'A','a','B','b','Y','y','Z','z',0}; /* Western and default */
62 static const WCHAR stSymbol[]={'S','y','m','b','o','l',0}; /* Symbol */
63 static const WCHAR stShiftJis[]={'A','a',0x3042,0x3041,0x30a2,0x30a1,0x4e9c,0x5b87,0}; /* Shift JIS */
64 static const WCHAR stHangul[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Hangul */
65 static const WCHAR stGB2312[]={0x5fae,0x8f6f,0x4e2d,0x6587,0x8f6f,0x4ef6,0}; /* GB2312 */
66 static const WCHAR stBIG5[]={0x4e2d,0x6587,0x5b57,0x578b,0x7bc4,0x4f8b,0}; /* BIG5 */
67 static const WCHAR stGreek[]={'A','a','B','b',0x0391,0x03b1,0x0392,0x03b2,0}; /* Greek */
68 static const WCHAR stTurkish[]={'A','a','B','b',0x011e,0x011f,0x015e,0x015f,0}; /* Turkish */
69 static const WCHAR stHebrew[]={'A','a','B','b',0x05e0,0x05e1,0x05e9,0x05ea,0}; /* Hebrew */
70 static const WCHAR stArabic[]={'A','a','B','b',0x0627,0x0628,0x062c,0x062f,0x0647,0x0648,0x0632,0};/* Arabic */
71 static const WCHAR stBaltic[]={'A','a','B','b','Y','y','Z','z',0}; /* Baltic */
72 static const WCHAR stVietname[]={'A','a','B','b',0x01a0,0x01a1,0x01af,0x01b0,0}; /* Vietnamese */
73 static const WCHAR stCyrillic[]={'A','a','B','b',0x0411,0x0431,0x0424,0x0444,0}; /* Cyrillic */
74 static const WCHAR stEastEur[]={'A','a','B','b',0xc1,0xe1,0xd4,0xf4,0}; /* East European */
75 static const WCHAR stThai[]={'A','a','B','b',0x0e2d,0x0e31,0x0e01,0x0e29,0x0e23,0x0e44,0x0e17,0x0e22,0}; /* Thai */
76 static const WCHAR stJohab[]={0xac00,0xb098,0xb2e4,'A','a','B','Y','y','Z','z',0}; /* Johab */
77 static const WCHAR stMac[]={'A','a','B','b','Y','y','Z','z',0}; /* Mac */
78 static const WCHAR stOEM[]={'A','a','B','b',0xf8,0xf1,0xfd,0}; /* OEM */
79 /* the following character sets actually behave different (Win2K observation):
80 * the sample string is 'sticky': it uses the sample string of the previous
81 * selected character set. That behaviour looks like some default, which is
82 * not (yet) implemented. */
83 static const WCHAR stVISCII[]={'A','a','B','b',0}; /* VISCII */
84 static const WCHAR stTCVN[]={'A','a','B','b',0}; /* TCVN */
85 static const WCHAR stKOI8[]={'A','a','B','b',0}; /* KOI-8 */
86 static const WCHAR stIso88593[]={'A','a','B','b',0}; /* ISO-8859-3 */
87 static const WCHAR stIso88594[]={'A','a','B','b',0}; /* ISO-8859-4 */
88 static const WCHAR stIso885910[]={'A','a','B','b',0}; /* ISO-8859-10 */
89 static const WCHAR stCeltic[]={'A','a','B','b',0};/* Celtic */
90
91 static const WCHAR * const sample_lang_text[]={
92 stWestern,stSymbol,stShiftJis,stHangul,stGB2312,
93 stBIG5,stGreek,stTurkish,stHebrew,stArabic,
94 stBaltic,stVietname,stCyrillic,stEastEur,stThai,
95 stJohab,stMac,stOEM,stVISCII,stTCVN,
96 stKOI8,stIso88593,stIso88594,stIso885910,stCeltic};
97
98
99 static const BYTE CHARSET_ORDER[256]={
100 CI(ANSI), 0, CI(SYMBOL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(MAC), 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 CI(JIS), CI(HANGUL), CI(JOHAB), 0, 0, 0, CI(GB2312), 0, CI(BIG5), 0, 0, 0, 0, 0, 0, 0,
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, CI(GREEK), CI(TURKISH), CI(VIETNAMESE), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, CI(HEBREW), CI(ARABIC), 0, 0, 0, 0, 0, 0, 0, CI(BALTIC), 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(RUSSIAN), 0, 0, 0,
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(THAI), 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CI(EE), 0,
115 CI(VISCII), CI(TCVN), CI(KOI8), CI(ISO3), CI(ISO4), CI(ISO10), CI(CELTIC), 0, 0, 0, 0, 0, 0, 0, 0, CI(OEM),
116 };
117
118 static const struct {
119 DWORD mask;
120 const char *name;
121 } cfflags[] = {
122 #define XX(x) { x, #x },
123 XX(CF_SCREENFONTS)
124 XX(CF_PRINTERFONTS)
125 XX(CF_SHOWHELP)
126 XX(CF_ENABLEHOOK)
127 XX(CF_ENABLETEMPLATE)
128 XX(CF_ENABLETEMPLATEHANDLE)
129 XX(CF_INITTOLOGFONTSTRUCT)
130 XX(CF_USESTYLE)
131 XX(CF_EFFECTS)
132 XX(CF_APPLY)
133 XX(CF_ANSIONLY)
134 XX(CF_NOVECTORFONTS)
135 XX(CF_NOSIMULATIONS)
136 XX(CF_LIMITSIZE)
137 XX(CF_FIXEDPITCHONLY)
138 XX(CF_WYSIWYG)
139 XX(CF_FORCEFONTEXIST)
140 XX(CF_SCALABLEONLY)
141 XX(CF_TTONLY)
142 XX(CF_NOFACESEL)
143 XX(CF_NOSTYLESEL)
144 XX(CF_NOSIZESEL)
145 XX(CF_SELECTSCRIPT)
146 XX(CF_NOSCRIPTSEL)
147 XX(CF_NOVERTFONTS)
148 #undef XX
149 };
150
151 void _dump_cf_flags(DWORD cflags)
152 {
153 int i;
154
155 for (i = 0; i < sizeof(cfflags)/sizeof(cfflags[0]); i++)
156 if (cfflags[i].mask & cflags)
157 TRACE("%s|",cfflags[i].name);
158 TRACE("\n");
159 }
160
161 /***********************************************************************
162 * ChooseFontW (COMDLG32.@)
163 *
164 * Create a font dialog box.
165 *
166 * PARAMS
167 * lpChFont [I/O] in: information to initialize the dialog box.
168 * out: User's color selection
169 *
170 * RETURNS
171 * TRUE: Ok button clicked.
172 * FALSE: Cancel button clicked, or error.
173 */
174 BOOL WINAPI ChooseFontW(LPCHOOSEFONTW lpChFont)
175 {
176 LPCVOID template;
177 HRSRC hResInfo;
178 HINSTANCE hDlginst;
179 HGLOBAL hDlgTmpl;
180
181 TRACE("(%p)\n", lpChFont);
182
183 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
184 {
185 template=(LPCVOID)lpChFont->hInstance;
186 } else
187 {
188 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
189 {
190 hDlginst=lpChFont->hInstance;
191 if( !(hResInfo = FindResourceW(hDlginst, lpChFont->lpTemplateName,
192 (LPWSTR)RT_DIALOG)))
193 {
194 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
195 return FALSE;
196 }
197 } else
198 {
199 hDlginst=COMDLG32_hInstance;
200 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
201 {
202 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
203 return FALSE;
204 }
205 }
206 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
207 !(template = LockResource( hDlgTmpl )))
208 {
209 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
210 return FALSE;
211 }
212 }
213 if (TRACE_ON(commdlg))
214 _dump_cf_flags(lpChFont->Flags);
215
216 if (lpChFont->Flags & (CF_SELECTSCRIPT | CF_NOVERTFONTS ))
217 FIXME(": unimplemented flag (ignored)\n");
218
219 return DialogBoxIndirectParamW(COMDLG32_hInstance, template,
220 lpChFont->hwndOwner, FormatCharDlgProcW, (LPARAM)lpChFont );
221 }
222
223 /***********************************************************************
224 * ChooseFontA (COMDLG32.@)
225 *
226 * See ChooseFontW.
227 */
228 BOOL WINAPI ChooseFontA(LPCHOOSEFONTA lpChFont)
229 {
230 LPCVOID template;
231 HRSRC hResInfo;
232 HINSTANCE hDlginst;
233 HGLOBAL hDlgTmpl;
234
235 TRACE("(%p)\n", lpChFont);
236
237 if ( (lpChFont->Flags&CF_ENABLETEMPLATEHANDLE)!=0 )
238 {
239 template=(LPCVOID)lpChFont->hInstance;
240 } else
241 {
242 if ( (lpChFont->Flags&CF_ENABLETEMPLATE)!=0 )
243 {
244 hDlginst=lpChFont->hInstance;
245 if( !(hResInfo = FindResourceA(hDlginst, lpChFont->lpTemplateName,
246 (LPSTR)RT_DIALOG)))
247 {
248 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
249 return FALSE;
250 }
251 } else
252 {
253 hDlginst=COMDLG32_hInstance;
254 if (!(hResInfo = FindResourceW(hDlginst, chooseFontW, (LPWSTR)RT_DIALOG)))
255 {
256 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
257 return FALSE;
258 }
259 }
260 if (!(hDlgTmpl = LoadResource(hDlginst, hResInfo )) ||
261 !(template = LockResource( hDlgTmpl )))
262 {
263 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
264 return FALSE;
265 }
266 }
267 if (TRACE_ON(commdlg))
268 _dump_cf_flags(lpChFont->Flags);
269 if (lpChFont->Flags & (CF_SELECTSCRIPT | CF_NOVERTFONTS ))
270 FIXME(": unimplemented flag (ignored)\n");
271
272 return DialogBoxIndirectParamA(COMDLG32_hInstance, template,
273 lpChFont->hwndOwner, FormatCharDlgProcA, (LPARAM)lpChFont );
274 }
275
276 #define TEXT_EXTRAS 4
277 #define TEXT_COLORS 16
278
279 static const COLORREF textcolors[TEXT_COLORS]=
280 {
281 0x00000000L,0x00000080L,0x00008000L,0x00008080L,
282 0x00800000L,0x00800080L,0x00808000L,0x00808080L,
283 0x00c0c0c0L,0x000000ffL,0x0000ff00L,0x0000ffffL,
284 0x00ff0000L,0x00ff00ffL,0x00ffff00L,0x00FFFFFFL
285 };
286
287 /***********************************************************************
288 * CFn_HookCallChk32 [internal]
289 */
290 static BOOL CFn_HookCallChk32(const CHOOSEFONTW *lpcf)
291 {
292 if (lpcf)
293 if(lpcf->Flags & CF_ENABLEHOOK)
294 if (lpcf->lpfnHook)
295 return TRUE;
296 return FALSE;
297 }
298
299 /*************************************************************************
300 * AddFontFamily [internal]
301 */
302 INT AddFontFamily(const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
303 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hwnd, LPCFn_ENUMSTRUCT e)
304 {
305 int i;
306 WORD w;
307 const LOGFONTW *lplf = &(lpElfex->elfLogFont);
308
309 TRACE("font=%s (nFontType=%d)\n", debugstr_w(lplf->lfFaceName), nFontType);
310
311 if (lpcf->Flags & CF_FIXEDPITCHONLY)
312 if (!(lplf->lfPitchAndFamily & FIXED_PITCH))
313 return 1;
314 if (lpcf->Flags & CF_ANSIONLY)
315 if (lplf->lfCharSet != ANSI_CHARSET)
316 return 1;
317 if (lpcf->Flags & CF_TTONLY)
318 if (!(nFontType & TRUETYPE_FONTTYPE))
319 return 1;
320
321 if (e) e->added++;
322
323 i=SendMessageW(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)lplf->lfFaceName);
324 if (i == CB_ERR) {
325 i = SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)lplf->lfFaceName);
326 if( i != CB_ERR) {
327 /* store some important font information */
328 w = (lplf->lfPitchAndFamily) << 8 |
329 (HIWORD(lpNTM->ntmTm.ntmFlags) & 0xff);
330 SendMessageW(hwnd, CB_SETITEMDATA, i, MAKELONG(nFontType,w));
331 }
332 }
333 return 1;
334 }
335
336 /*************************************************************************
337 * FontFamilyEnumProc32 [internal]
338 */
339 static INT WINAPI FontFamilyEnumProc(const ENUMLOGFONTEXW *lpElfex,
340 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam)
341 {
342 LPCFn_ENUMSTRUCT e;
343 e=(LPCFn_ENUMSTRUCT)lParam;
344 return AddFontFamily( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
345 dwFontType, e->lpcf32w, e->hWnd1, e);
346 }
347
348 /*************************************************************************
349 * SetFontStylesToCombo2 [internal]
350 *
351 * Fill font style information into combobox (without using font.c directly)
352 */
353 static int SetFontStylesToCombo2(HWND hwnd, HDC hdc, const LOGFONTW *lplf)
354 {
355 #define FSTYLES 4
356 struct FONTSTYLE
357 {
358 int italic;
359 int weight;
360 UINT resId;
361 };
362 static const struct FONTSTYLE fontstyles[FSTYLES]={
363 { 0, FW_NORMAL, IDS_FONT_REGULAR },
364 { 1, FW_NORMAL, IDS_FONT_ITALIC },
365 { 0, FW_BOLD, IDS_FONT_BOLD },
366 { 1, FW_BOLD, IDS_FONT_BOLD_ITALIC }
367 };
368 HFONT hf;
369 TEXTMETRICW tm;
370 int i,j;
371 LOGFONTW lf;
372
373 lf = *lplf;
374
375 for (i=0;i<FSTYLES;i++)
376 {
377 lf.lfItalic=fontstyles[i].italic;
378 lf.lfWeight=fontstyles[i].weight;
379 hf=CreateFontIndirectW(&lf);
380 hf=SelectObject(hdc,hf);
381 GetTextMetricsW(hdc,&tm);
382 hf=SelectObject(hdc,hf);
383 DeleteObject(hf);
384 /* font successful created ? */
385 if (((fontstyles[i].weight == FW_NORMAL && tm.tmWeight <= FW_MEDIUM) ||
386 (fontstyles[i].weight == FW_BOLD && tm.tmWeight > FW_MEDIUM)) &&
387 ((tm.tmItalic != 0)==fontstyles[i].italic))
388 {
389 WCHAR name[64];
390 LoadStringW(COMDLG32_hInstance, fontstyles[i].resId, name, 64);
391 j=SendMessageW(hwnd,CB_ADDSTRING,0,(LPARAM)name );
392 if (j==CB_ERR) return 1;
393 j=SendMessageW(hwnd, CB_SETITEMDATA, j,
394 MAKELONG(tm.tmWeight,fontstyles[i].italic));
395 if (j==CB_ERR) return 1;
396 }
397 }
398 return 0;
399 }
400
401 /*************************************************************************
402 * AddFontSizeToCombo3 [internal]
403 */
404 static int AddFontSizeToCombo3(HWND hwnd, UINT h, const CHOOSEFONTW *lpcf)
405 {
406 int j;
407 WCHAR buffer[20];
408 static const WCHAR strFormat[] = {'%','2','d',0};
409
410 if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
411 ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
412 {
413 wsprintfW(buffer, strFormat, h);
414 j=SendMessageW(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)buffer);
415 if (j==CB_ERR)
416 {
417 j=SendMessageW(hwnd, CB_ADDSTRING, 0, (LPARAM)buffer);
418 if (j!=CB_ERR) j = SendMessageW(hwnd, CB_SETITEMDATA, j, h);
419 if (j==CB_ERR) return 1;
420 }
421 }
422 return 0;
423 }
424
425 /*************************************************************************
426 * SetFontSizesToCombo3 [internal]
427 */
428 static int SetFontSizesToCombo3(HWND hwnd, const CHOOSEFONTW *lpcf)
429 {
430 static const BYTE sizes[]={6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
431 int i;
432
433 for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++)
434 if (AddFontSizeToCombo3(hwnd, sizes[i], lpcf)) return 1;
435 return 0;
436 }
437
438 /*************************************************************************
439 * CFn_GetDC [internal]
440 */
441 static inline HDC CFn_GetDC(const CHOOSEFONTW *lpcf)
442 {
443 HDC ret = ((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC) ?
444 lpcf->hDC :
445 GetDC(0);
446 if(!ret) ERR("HDC failure!!!\n");
447 return ret;
448 }
449
450 /*************************************************************************
451 * CFn_ReleaseDC [internal]
452 */
453 static inline void CFn_ReleaseDC(const CHOOSEFONTW *lpcf, HDC hdc)
454 {
455 if(!((lpcf->Flags & CF_PRINTERFONTS) && lpcf->hDC))
456 ReleaseDC(0, hdc);
457 }
458
459 /***********************************************************************
460 * AddFontStyle [internal]
461 */
462 INT AddFontStyle( const ENUMLOGFONTEXW *lpElfex, const NEWTEXTMETRICEXW *lpNTM,
463 UINT nFontType, const CHOOSEFONTW *lpcf, HWND hcmb2, HWND hcmb3,
464 HWND hDlg, BOOL iswin16)
465 {
466 int i;
467 const LOGFONTW *lplf = &(lpElfex->elfLogFont);
468 HWND hcmb5;
469 HDC hdc;
470
471 TRACE("(nFontType=%d)\n",nFontType);
472 TRACE(" %s h=%d w=%d e=%d o=%d wg=%d i=%d u=%d s=%d"
473 " ch=%d op=%d cp=%d q=%d pf=%xh\n",
474 debugstr_w(lplf->lfFaceName),lplf->lfHeight,lplf->lfWidth,
475 lplf->lfEscapement,lplf->lfOrientation,
476 lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline,
477 lplf->lfStrikeOut,lplf->lfCharSet, lplf->lfOutPrecision,
478 lplf->lfClipPrecision,lplf->lfQuality, lplf->lfPitchAndFamily);
479 if (nFontType & RASTER_FONTTYPE)
480 {
481 INT points;
482 if(!(hdc = CFn_GetDC(lpcf))) return 0;
483 points = MulDiv( lpNTM->ntmTm.tmHeight - lpNTM->ntmTm.tmInternalLeading,
484 72, GetDeviceCaps(hdc, LOGPIXELSY));
485 CFn_ReleaseDC(lpcf, hdc);
486 i = AddFontSizeToCombo3(hcmb3, points, lpcf);
487 if(i) return 0;
488 } else if (SetFontSizesToCombo3(hcmb3, lpcf)) return 0;
489
490 if (!SendMessageW(hcmb2, CB_GETCOUNT, 0, 0))
491 {
492 if(!(hdc = CFn_GetDC(lpcf))) return 0;
493 i=SetFontStylesToCombo2(hcmb2,hdc,lplf);
494 CFn_ReleaseDC(lpcf, hdc);
495 if (i)
496 return 0;
497 }
498 if( iswin16 || !( hcmb5 = GetDlgItem(hDlg, cmb5))) return 1;
499 i = SendMessageW( hcmb5, CB_FINDSTRINGEXACT, 0,
500 (LPARAM)lpElfex->elfScript);
501 if( i == CB_ERR) {
502 i = SendMessageW( hcmb5, CB_ADDSTRING, 0,
503 (LPARAM)lpElfex->elfScript);
504 if( i != CB_ERR)
505 SendMessageW( hcmb5, CB_SETITEMDATA, i, lplf->lfCharSet);
506 }
507 return 1 ;
508 }
509
510 static INT CFn_FitFontSize( HWND hDlg, int points)
511 {
512 int i,n;
513 int ret = 0;
514 /* look for fitting font size in combobox3 */
515 n=SendDlgItemMessageW(hDlg, cmb3, CB_GETCOUNT, 0, 0);
516 for (i=0;i<n;i++)
517 {
518 if (points == (int)SendDlgItemMessageW
519 (hDlg,cmb3, CB_GETITEMDATA,i,0))
520 {
521 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,i,0);
522 SendMessageW(hDlg, WM_COMMAND,
523 MAKEWPARAM(cmb3, CBN_SELCHANGE),
524 (LPARAM)GetDlgItem(hDlg,cmb3));
525 ret = 1;
526 break;
527 }
528 }
529 return ret;
530 }
531
532 static INT CFn_FitFontStyle( HWND hDlg, LONG packedstyle )
533 {
534 LONG id;
535 int i, ret = 0;
536 /* look for fitting font style in combobox2 */
537 for (i=0;i<TEXT_EXTRAS;i++)
538 {
539 id = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0);
540 if (packedstyle == id)
541 {
542 SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0);
543 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
544 (LPARAM)GetDlgItem(hDlg,cmb2));
545 ret = 1;
546 break;
547 }
548 }
549 return ret;
550 }
551
552
553 static INT CFn_FitCharSet( HWND hDlg, int charset )
554 {
555 int i,n,cs;
556 /* look for fitting char set in combobox5 */
557 n=SendDlgItemMessageW(hDlg, cmb5, CB_GETCOUNT, 0, 0);
558 for (i=0;i<n;i++)
559 {
560 cs =SendDlgItemMessageW(hDlg, cmb5, CB_GETITEMDATA, i, 0);
561 if (charset == cs)
562 {
563 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, i, 0);
564 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
565 (LPARAM)GetDlgItem(hDlg,cmb2));
566 return 1;
567 }
568 }
569 /* no charset fits: select the first one in the list */
570 SendDlgItemMessageW(hDlg, cmb5, CB_SETCURSEL, 0, 0);
571 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
572 (LPARAM)GetDlgItem(hDlg,cmb2));
573 return 0;
574 }
575
576 /***********************************************************************
577 * FontStyleEnumProc32 [internal]
578 */
579 static INT WINAPI FontStyleEnumProc( const ENUMLOGFONTEXW *lpElfex,
580 const TEXTMETRICW *metrics, DWORD dwFontType, LPARAM lParam )
581 {
582 LPCFn_ENUMSTRUCT s=(LPCFn_ENUMSTRUCT)lParam;
583 HWND hcmb2=s->hWnd1;
584 HWND hcmb3=s->hWnd2;
585 HWND hDlg=GetParent(hcmb3);
586 return AddFontStyle( lpElfex, (const NEWTEXTMETRICEXW *) metrics,
587 dwFontType, s->lpcf32w, hcmb2, hcmb3, hDlg, FALSE);
588 }
589
590 /***********************************************************************
591 * CFn_WMInitDialog [internal]
592 */
593 LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam,
594 LPCHOOSEFONTW lpcf)
595 {
596 HDC hdc;
597 int i,j,init=0;
598 long pstyle;
599 CFn_ENUMSTRUCT s;
600 LPLOGFONTW lpxx;
601 HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));
602 static const WCHAR strColorName[] = {'[','c','o','l','o','r',' ','n','a','m','e',']',0};
603
604 SetPropW(hDlg, strWineFontData, (HANDLE)lpcf);
605 lpxx=lpcf->lpLogFont;
606 TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
607
608 if (lpcf->lStructSize != sizeof(CHOOSEFONTW))
609 {
610 ERR("structure size failure !!!\n");
611 EndDialog (hDlg, 0);
612 return FALSE;
613 }
614 if (!himlTT)
615 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
616 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
617
618 /* Set effect flags */
619 if((lpcf->Flags & CF_EFFECTS) && (lpcf->Flags & CF_INITTOLOGFONTSTRUCT))
620 {
621 if(lpxx->lfUnderline)
622 CheckDlgButton(hDlg, chx2, TRUE);
623 if(lpxx->lfStrikeOut)
624 CheckDlgButton(hDlg, chx1, TRUE);
625 }
626
627 if (!(lpcf->Flags & CF_SHOWHELP) || !IsWindow(lpcf->hwndOwner))
628 ShowWindow(GetDlgItem(hDlg,pshHelp),SW_HIDE);
629 if (!(lpcf->Flags & CF_APPLY))
630 ShowWindow(GetDlgItem(hDlg,psh3),SW_HIDE);
631 if (lpcf->Flags & CF_NOSCRIPTSEL)
632 EnableWindow(GetDlgItem(hDlg,cmb5),FALSE);
633 if (lpcf->Flags & CF_EFFECTS)
634 {
635 for (i=0;i<TEXT_COLORS;i++)
636 {
637 WCHAR name[30];
638
639 if( LoadStringW(COMDLG32_hInstance, IDS_COLOR_BLACK+i, name,
640 sizeof(name)/sizeof(*name) )==0 )
641 {
642 memcpy(name, strColorName, sizeof(strColorName));
643 }
644 j=SendDlgItemMessageW(hDlg, cmb4, CB_ADDSTRING, 0, (LPARAM)name);
645 SendDlgItemMessageW(hDlg, cmb4, CB_SETITEMDATA, j, textcolors[i]);
646 /* look for a fitting value in color combobox */
647 if (textcolors[i]==lpcf->rgbColors)
648 SendDlgItemMessageW(hDlg,cmb4, CB_SETCURSEL,j,0);
649 }
650 }
651 else
652 {
653 ShowWindow(GetDlgItem(hDlg,cmb4),SW_HIDE);
654 ShowWindow(GetDlgItem(hDlg,chx1),SW_HIDE);
655 ShowWindow(GetDlgItem(hDlg,chx2),SW_HIDE);
656 ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
657 ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
658 }
659 if(!(hdc = CFn_GetDC(lpcf)))
660 {
661 EndDialog (hDlg, 0);
662 return FALSE;
663 }
664 s.hWnd1=GetDlgItem(hDlg,cmb1);
665 s.lpcf32w=lpcf;
666 do {
667 LOGFONTW elf;
668 s.added = 0;
669 elf.lfCharSet = DEFAULT_CHARSET; /* enum all charsets */
670 elf.lfPitchAndFamily = 0;
671 elf.lfFaceName[0] = '\0'; /* enum all fonts */
672 if (!EnumFontFamiliesExW(hdc, &elf, (FONTENUMPROCW)FontFamilyEnumProc, (LPARAM)&s, 0))
673 {
674 TRACE("EnumFontFamiliesEx returns 0\n");
675 break;
676 }
677 if (s.added) break;
678 if (lpcf->Flags & CF_FIXEDPITCHONLY) {
679 FIXME("No font found with fixed pitch only, dropping flag.\n");
680 lpcf->Flags &= ~CF_FIXEDPITCHONLY;
681 continue;
682 }
683 if (lpcf->Flags & CF_TTONLY) {
684 FIXME("No font found with truetype only, dropping flag.\n");
685 lpcf->Flags &= ~CF_TTONLY;
686 continue;
687 }
688 break;
689 } while (1);
690
691
692 if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
693 {
694 /* look for fitting font name in combobox1 */
695 j=SendDlgItemMessageW(hDlg,cmb1,CB_FINDSTRING,-1,(LPARAM)lpxx->lfFaceName);
696 if (j!=CB_ERR)
697 {
698 INT height = lpxx->lfHeight < 0 ? -lpxx->lfHeight :
699 lpxx->lfHeight;
700 INT points;
701 int charset = lpxx->lfCharSet;
702 points = MulDiv( height, 72, GetDeviceCaps(hdc, LOGPIXELSY));
703 pstyle = MAKELONG(lpxx->lfWeight > FW_MEDIUM ? FW_BOLD:
704 FW_NORMAL,lpxx->lfItalic !=0);
705 SendDlgItemMessageW(hDlg, cmb1, CB_SETCURSEL, j, 0);
706 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
707 (LPARAM)GetDlgItem(hDlg,cmb1));
708 init=1;
709 /* look for fitting font style in combobox2 */
710 CFn_FitFontStyle(hDlg, pstyle);
711 /* look for fitting font size in combobox3 */
712 CFn_FitFontSize(hDlg, points);
713 CFn_FitCharSet( hDlg, charset );
714 }
715 }
716 if (!init)
717 {
718 SendDlgItemMessageW(hDlg,cmb1,CB_SETCURSEL,0,0);
719 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),
720 (LPARAM)GetDlgItem(hDlg,cmb1));
721 SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,0,0);
722 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb2, CBN_SELCHANGE),
723 (LPARAM)GetDlgItem(hDlg,cmb1));
724 SendDlgItemMessageW(hDlg,cmb3,CB_SETCURSEL,0,0);
725 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb3, CBN_SELCHANGE),
726 (LPARAM)GetDlgItem(hDlg,cmb3));
727 SendDlgItemMessageW(hDlg,cmb5,CB_SETCURSEL,0,0);
728 SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb5, CBN_SELCHANGE),
729 (LPARAM)GetDlgItem(hDlg,cmb5));
730 }
731 if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)
732 {
733 j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LPARAM)lpcf->lpszStyle);
734 if (j!=CB_ERR)
735 {
736 j=SendDlgItemMessageW(hDlg,cmb2,CB_SETCURSEL,j,0);
737 SendMessageW(hDlg,WM_COMMAND,cmb2,
738 MAKELONG(HWND_16(GetDlgItem(hDlg,cmb2)),CBN_SELCHANGE));
739 }
740 }
741 CFn_ReleaseDC(lpcf, hdc);
742 SetCursor(hcursor);
743 return TRUE;
744 }
745
746
747 /***********************************************************************
748 * CFn_WMMeasureItem [internal]
749 */
750 LRESULT CFn_WMMeasureItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
751 {
752 HDC hdc;
753 HFONT hfontprev;
754 TEXTMETRICW tm;
755 LPMEASUREITEMSTRUCT lpmi=(LPMEASUREITEMSTRUCT)lParam;
756 INT height = 0;
757
758 if (!himlTT)
759 himlTT = ImageList_LoadImageW( COMDLG32_hInstance, MAKEINTRESOURCEW(38),
760 TTBITMAP_XSIZE, 0, CLR_DEFAULT, IMAGE_BITMAP, 0);
761 ImageList_GetIconSize( himlTT, 0, &height);
762 lpmi->itemHeight = height + 2;
763 /* use MAX of bitmap height and tm.tmHeight .*/
764 hdc=GetDC(hDlg);
765 if(!hdc) return 0;
766 hfontprev = SelectObject( hdc, GetStockObject( SYSTEM_FONT));
767 GetTextMetricsW(hdc, &tm);
768 if( tm.tmHeight > lpmi->itemHeight) lpmi->itemHeight = tm.tmHeight;
769 SelectObject(hdc, hfontprev);
770 ReleaseDC(hDlg, hdc);
771 return 0;
772 }
773
774
775 /***********************************************************************
776 * CFn_WMDrawItem [internal]
777 */
778 LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
779 {
780 HBRUSH hBrush;
781 WCHAR buffer[40];
782 COLORREF cr, oldText=0, oldBk=0;
783 RECT rect;
784 int nFontType;
785 int idx;
786 LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
787
788 if (lpdi->itemID == (UINT)-1) /* got no items */
789 DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
790 else
791 {
792 if (lpdi->CtlType == ODT_COMBOBOX)
793 {
794 if (lpdi->itemState & ODS_SELECTED)
795 {
796 hBrush=GetSysColorBrush(COLOR_HIGHLIGHT);
797 oldText=SetTextColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
798 oldBk=SetBkColor(lpdi->hDC, GetSysColor(COLOR_HIGHLIGHT));
799 } else
800 {
801 hBrush = SelectObject(lpdi->hDC, GetStockObject(LTGRAY_BRUSH));
802 SelectObject(lpdi->hDC, hBrush);
803 }
804 FillRect(lpdi->hDC, &lpdi->rcItem, hBrush);
805 }
806 else
807 return TRUE; /* this should never happen */
808
809 rect=lpdi->rcItem;
810 switch (lpdi->CtlID)
811 {
812 case cmb1:
813 /* TRACE(commdlg,"WM_Drawitem cmb1\n"); */
814 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
815 (LPARAM)buffer);
816 TextOutW(lpdi->hDC, lpdi->rcItem.left + TTBITMAP_XSIZE + 10,
817 lpdi->rcItem.top, buffer, lstrlenW(buffer));
818 nFontType = SendMessageW(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
819 idx = -1;
820 if (nFontType & TRUETYPE_FONTTYPE) {
821 idx = 0; /* picture: TT */
822 if( nFontType & NTM_TT_OPENTYPE)
823 idx = 2; /* picture: O */
824 } else if( nFontType & NTM_PS_OPENTYPE)
825 idx = 3; /* picture: O+ps */
826 else if( nFontType & NTM_TYPE1)
827 idx = 4; /* picture: a */
828 else if( nFontType & DEVICE_FONTTYPE)
829 idx = 1; /* picture: printer */
830 if( idx >= 0)
831 ImageList_Draw( himlTT, idx, lpdi->hDC, lpdi->rcItem.left,
832 lpdi->rcItem.top, ILD_TRANSPARENT);
833 break;
834 case cmb2:
835 case cmb3:
836 /* TRACE(commdlg,"WM_DRAWITEN cmb2,cmb3\n"); */
837 case cmb5:
838 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
839 (LPARAM)buffer);
840 TextOutW(lpdi->hDC, lpdi->rcItem.left,
841 lpdi->rcItem.top, buffer, lstrlenW(buffer));
842 break;
843
844 case cmb4:
845 /* TRACE(commdlg,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
846 SendMessageW(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
847 (LPARAM)buffer);
848 TextOutW(lpdi->hDC, lpdi->rcItem.left + 25+5,
849 lpdi->rcItem.top, buffer, lstrlenW(buffer));
850 cr = SendMessageW(lpdi->hwndItem,