~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/comdlg32/fontdlg.c

Version: ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  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,