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

Wine Cross Reference
wine/dlls/gdi32/font.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  * GDI font objects
  3  *
  4  * Copyright 1993 Alexandre Julliard
  5  *           1997 Alex Korobka
  6  * Copyright 2002,2003 Shachar Shemesh
  7  *
  8  * This library is free software; you can redistribute it and/or
  9  * modify it under the terms of the GNU Lesser General Public
 10  * License as published by the Free Software Foundation; either
 11  * version 2.1 of the License, or (at your option) any later version.
 12  *
 13  * This library 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 GNU
 16  * Lesser General Public License for more details.
 17  *
 18  * You should have received a copy of the GNU Lesser General Public
 19  * License along with this library; if not, write to the Free Software
 20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 21  */
 22 
 23 #include "config.h"
 24 #include "wine/port.h"
 25 
 26 #include <stdarg.h>
 27 #include <stdlib.h>
 28 #include <string.h>
 29 #include <assert.h>
 30 #include "winerror.h"
 31 #include "windef.h"
 32 #include "winbase.h"
 33 #include "winnls.h"
 34 #include "wownt32.h"
 35 #include "gdi_private.h"
 36 #include "wine/unicode.h"
 37 #include "wine/debug.h"
 38 
 39 WINE_DEFAULT_DEBUG_CHANNEL(font);
 40 
 41   /* Device -> World size conversion */
 42 
 43 /* Performs a device to world transformation on the specified width (which
 44  * is in integer format).
 45  */
 46 static inline INT INTERNAL_XDSTOWS(DC *dc, INT width)
 47 {
 48     FLOAT floatWidth;
 49 
 50     /* Perform operation with floating point */
 51     floatWidth = (FLOAT)width * dc->xformVport2World.eM11;
 52     /* Round to integers */
 53     return GDI_ROUND(floatWidth);
 54 }
 55 
 56 /* Performs a device to world transformation on the specified size (which
 57  * is in integer format).
 58  */
 59 static inline INT INTERNAL_YDSTOWS(DC *dc, INT height)
 60 {
 61     FLOAT floatHeight;
 62 
 63     /* Perform operation with floating point */
 64     floatHeight = (FLOAT)height * dc->xformVport2World.eM22;
 65     /* Round to integers */
 66     return GDI_ROUND(floatHeight);
 67 }
 68 
 69 static inline INT INTERNAL_XWSTODS(DC *dc, INT width)
 70 {
 71     POINT pt[2];
 72     pt[0].x = pt[0].y = 0;
 73     pt[1].x = width;
 74     pt[1].y = 0;
 75     LPtoDP(dc->hSelf, pt, 2);
 76     return pt[1].x - pt[0].x;
 77 }
 78 
 79 static inline INT INTERNAL_YWSTODS(DC *dc, INT height)
 80 {
 81     POINT pt[2];
 82     pt[0].x = pt[0].y = 0;
 83     pt[1].x = 0;
 84     pt[1].y = height;
 85     LPtoDP(dc->hSelf, pt, 2);
 86     return pt[1].y - pt[0].y;
 87 }
 88 
 89 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, HDC hdc );
 90 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
 91 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
 92 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
 93 
 94 static const struct gdi_obj_funcs font_funcs =
 95 {
 96     FONT_SelectObject,  /* pSelectObject */
 97     FONT_GetObjectA,    /* pGetObjectA */
 98     FONT_GetObjectW,    /* pGetObjectW */
 99     NULL,               /* pUnrealizeObject */
100     FONT_DeleteObject   /* pDeleteObject */
101 };
102 
103 #define ENUM_UNICODE    0x00000001
104 #define ENUM_CALLED     0x00000002
105 
106 typedef struct
107 {
108     GDIOBJHDR   header;
109     LOGFONTW    logfont;
110 } FONTOBJ;
111 
112 typedef struct
113 {
114   LPLOGFONTW          lpLogFontParam;
115   FONTENUMPROCW       lpEnumFunc;
116   LPARAM              lpData;
117   DWORD               dwFlags;
118   HDC                 hdc;
119 } fontEnum32;
120 
121 /*
122  *  For TranslateCharsetInfo
123  */
124 #define MAXTCIINDEX 32
125 static const CHARSETINFO FONT_tci[MAXTCIINDEX] = {
126   /* ANSI */
127   { ANSI_CHARSET, 1252, {{0,0,0,0},{FS_LATIN1,0}} },
128   { EASTEUROPE_CHARSET, 1250, {{0,0,0,0},{FS_LATIN2,0}} },
129   { RUSSIAN_CHARSET, 1251, {{0,0,0,0},{FS_CYRILLIC,0}} },
130   { GREEK_CHARSET, 1253, {{0,0,0,0},{FS_GREEK,0}} },
131   { TURKISH_CHARSET, 1254, {{0,0,0,0},{FS_TURKISH,0}} },
132   { HEBREW_CHARSET, 1255, {{0,0,0,0},{FS_HEBREW,0}} },
133   { ARABIC_CHARSET, 1256, {{0,0,0,0},{FS_ARABIC,0}} },
134   { BALTIC_CHARSET, 1257, {{0,0,0,0},{FS_BALTIC,0}} },
135   { VIETNAMESE_CHARSET, 1258, {{0,0,0,0},{FS_VIETNAMESE,0}} },
136   /* reserved by ANSI */
137   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
138   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
139   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
140   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
141   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
142   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
143   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
144   /* ANSI and OEM */
145   { THAI_CHARSET, 874, {{0,0,0,0},{FS_THAI,0}} },
146   { SHIFTJIS_CHARSET, 932, {{0,0,0,0},{FS_JISJAPAN,0}} },
147   { GB2312_CHARSET, 936, {{0,0,0,0},{FS_CHINESESIMP,0}} },
148   { HANGEUL_CHARSET, 949, {{0,0,0,0},{FS_WANSUNG,0}} },
149   { CHINESEBIG5_CHARSET, 950, {{0,0,0,0},{FS_CHINESETRAD,0}} },
150   { JOHAB_CHARSET, 1361, {{0,0,0,0},{FS_JOHAB,0}} },
151   /* reserved for alternate ANSI and OEM */
152   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
153   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
154   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
155   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
156   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
157   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
158   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
159   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
160   /* reserved for system */
161   { DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
162   { SYMBOL_CHARSET, CP_SYMBOL, {{0,0,0,0},{FS_SYMBOL,0}} }
163 };
164 
165 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
166 {
167     memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
168     MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
169                         LF_FACESIZE);
170     fontW->lfFaceName[LF_FACESIZE-1] = 0;
171 }
172 
173 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
174 {
175     memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
176     WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
177                         LF_FACESIZE, NULL, NULL);
178     fontA->lfFaceName[LF_FACESIZE-1] = 0;
179 }
180 
181 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
182 {
183     FONT_LogFontWToA( (const LOGFONTW *)fontW, (LPLOGFONTA)fontA);
184 
185     WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
186                          (LPSTR) fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
187     fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
188     WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
189                          (LPSTR) fontA->elfStyle, LF_FACESIZE, NULL, NULL );
190     fontA->elfStyle[LF_FACESIZE-1] = '\0';
191     WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
192                          (LPSTR) fontA->elfScript, LF_FACESIZE, NULL, NULL );
193     fontA->elfScript[LF_FACESIZE-1] = '\0';
194 }
195 
196 /***********************************************************************
197  *              TEXTMETRIC conversion functions.
198  */
199 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
200 {
201     ptmA->tmHeight = ptmW->tmHeight;
202     ptmA->tmAscent = ptmW->tmAscent;
203     ptmA->tmDescent = ptmW->tmDescent;
204     ptmA->tmInternalLeading = ptmW->tmInternalLeading;
205     ptmA->tmExternalLeading = ptmW->tmExternalLeading;
206     ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
207     ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
208     ptmA->tmWeight = ptmW->tmWeight;
209     ptmA->tmOverhang = ptmW->tmOverhang;
210     ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
211     ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
212     ptmA->tmFirstChar = min(ptmW->tmFirstChar, 255);
213     if (ptmW->tmCharSet == SYMBOL_CHARSET)
214     {
215         UINT last_char = ptmW->tmLastChar;
216         if (last_char > 0xf000) last_char -= 0xf000;
217         ptmA->tmLastChar = min(last_char, 255);
218     }
219     else
220         ptmA->tmLastChar = min(ptmW->tmLastChar, 255);
221     ptmA->tmDefaultChar = min(ptmW->tmDefaultChar, 255);
222     ptmA->tmBreakChar = min(ptmW->tmBreakChar, 255);
223     ptmA->tmItalic = ptmW->tmItalic;
224     ptmA->tmUnderlined = ptmW->tmUnderlined;
225     ptmA->tmStruckOut = ptmW->tmStruckOut;
226     ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
227     ptmA->tmCharSet = ptmW->tmCharSet;
228 }
229 
230 
231 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
232 {
233     FONT_TextMetricWToA((const TEXTMETRICW *)ptmW, (LPTEXTMETRICA)ptmA);
234     ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
235     ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
236     ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
237     ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
238     memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
239 }
240 
241 
242 /***********************************************************************
243  *           GdiGetCodePage   (GDI32.@)
244  */
245 DWORD WINAPI GdiGetCodePage( HDC hdc )
246 {
247     UINT cp = CP_ACP;
248     CHARSETINFO csi;
249     int charset = GetTextCharset(hdc);
250 
251     /* Hmm, nicely designed api this one! */
252     if(TranslateCharsetInfo(ULongToPtr(charset), &csi, TCI_SRCCHARSET))
253         cp = csi.ciACP;
254     else {
255         switch(charset) {
256         case OEM_CHARSET:
257             cp = GetOEMCP();
258             break;
259         case DEFAULT_CHARSET:
260             cp = GetACP();
261             break;
262 
263         case VISCII_CHARSET:
264         case TCVN_CHARSET:
265         case KOI8_CHARSET:
266         case ISO3_CHARSET:
267         case ISO4_CHARSET:
268         case ISO10_CHARSET:
269         case CELTIC_CHARSET:
270             /* FIXME: These have no place here, but because x11drv
271                enumerates fonts with these (made up) charsets some apps
272                might use them and then the FIXME below would become
273                annoying.  Now we could pick the intended codepage for
274                each of these, but since it's broken anyway we'll just
275                use CP_ACP and hope it'll go away...
276             */
277             cp = CP_ACP;
278             break;
279 
280         default:
281             FIXME("Can't find codepage for charset %d\n", charset);
282             break;
283         }
284     }
285 
286     TRACE("charset %d => cp %d\n", charset, cp);
287     return cp;
288 }
289 
290 /***********************************************************************
291  *           FONT_mbtowc
292  *
293  * Returns a Unicode translation of str using the charset of the
294  * currently selected font in hdc.  If count is -1 then str is assumed
295  * to be '\0' terminated, otherwise it contains the number of bytes to
296  * convert.  If plenW is non-NULL, on return it will point to the
297  * number of WCHARs that have been written.  If pCP is non-NULL, on
298  * return it will point to the codepage used in the conversion.  The
299  * caller should free the returned LPWSTR from the process heap
300  * itself.
301  */
302 static LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
303 {
304     UINT cp;
305     INT lenW;
306     LPWSTR strW;
307 
308     cp = GdiGetCodePage( hdc );
309 
310     if(count == -1) count = strlen(str);
311     lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
312     strW = HeapAlloc(GetProcessHeap(), 0, lenW*sizeof(WCHAR));
313     MultiByteToWideChar(cp, 0, str, count, strW, lenW);
314     TRACE("mapped %s -> %s\n", debugstr_an(str, count), debugstr_wn(strW, lenW));
315     if(plenW) *plenW = lenW;
316     if(pCP) *pCP = cp;
317     return strW;
318 }
319 
320 
321 /***********************************************************************
322  *           CreateFontIndirectA   (GDI32.@)
323  */
324 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
325 {
326     LOGFONTW lfW;
327 
328     if (!plfA) return 0;
329 
330     FONT_LogFontAToW( plfA, &lfW );
331     return CreateFontIndirectW( &lfW );
332 }
333 
334 /***********************************************************************
335  *           CreateFontIndirectW   (GDI32.@)
336  */
337 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
338 {
339     static const WCHAR ItalicW[] = {' ','I','t','a','l','i','c','\0'};
340     static const WCHAR BoldW[]   = {' ','B','o','l','d','\0'};
341     WCHAR *pFaceNameItalicSuffix, *pFaceNameBoldSuffix;
342     WCHAR *pFaceNameSuffix = NULL;
343     HFONT hFont;
344     FONTOBJ *fontPtr;
345 
346     if (!plf) return 0;
347 
348     if (!(fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, (HGDIOBJ *)&hFont,
349                                      &font_funcs ))) return 0;
350 
351     fontPtr->logfont = *plf;
352 
353     TRACE("(%d %d %d %d %x %d %x %d %d) %s %s %s %s => %p\n",
354           plf->lfHeight, plf->lfWidth,
355           plf->lfEscapement, plf->lfOrientation,
356           plf->lfPitchAndFamily,
357           plf->lfOutPrecision, plf->lfClipPrecision,
358           plf->lfQuality, plf->lfCharSet,
359           debugstr_w(plf->lfFaceName),
360           plf->lfWeight > 400 ? "Bold" : "",
361           plf->lfItalic ? "Italic" : "",
362           plf->lfUnderline ? "Underline" : "", hFont);
363 
364     if (plf->lfEscapement != plf->lfOrientation)
365     {
366         /* this should really depend on whether GM_ADVANCED is set */
367         fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
368         WARN("orientation angle %f set to "
369              "escapement angle %f for new font %p\n",
370              plf->lfOrientation/10., plf->lfEscapement/10., hFont);
371     }
372 
373     pFaceNameItalicSuffix = strstrW(fontPtr->logfont.lfFaceName, ItalicW);
374     if (pFaceNameItalicSuffix)
375     {
376         fontPtr->logfont.lfItalic = TRUE;
377         pFaceNameSuffix = pFaceNameItalicSuffix;
378     }
379 
380     pFaceNameBoldSuffix = strstrW(fontPtr->logfont.lfFaceName, BoldW);
381     if (pFaceNameBoldSuffix)
382     {
383         if (fontPtr->logfont.lfWeight < FW_BOLD)
384             fontPtr->logfont.lfWeight = FW_BOLD;
385         if (!pFaceNameSuffix || (pFaceNameBoldSuffix < pFaceNameSuffix))
386             pFaceNameSuffix = pFaceNameBoldSuffix;
387     }
388 
389     if (pFaceNameSuffix) *pFaceNameSuffix = 0;
390 
391     GDI_ReleaseObj( hFont );
392     return hFont;
393 }
394 
395 /*************************************************************************
396  *           CreateFontA    (GDI32.@)
397  */
398 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
399                               INT orient, INT weight, DWORD italic,
400                               DWORD underline, DWORD strikeout, DWORD charset,
401                               DWORD outpres, DWORD clippres, DWORD quality,
402                               DWORD pitch, LPCSTR name )
403 {
404     LOGFONTA logfont;
405 
406     logfont.lfHeight = height;
407     logfont.lfWidth = width;
408     logfont.lfEscapement = esc;
409     logfont.lfOrientation = orient;
410     logfont.lfWeight = weight;
411     logfont.lfItalic = italic;
412     logfont.lfUnderline = underline;
413     logfont.lfStrikeOut = strikeout;
414     logfont.lfCharSet = charset;
415     logfont.lfOutPrecision = outpres;
416     logfont.lfClipPrecision = clippres;
417     logfont.lfQuality = quality;
418     logfont.lfPitchAndFamily = pitch;
419 
420     if (name)
421         lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
422     else
423         logfont.lfFaceName[0] = '\0';
424 
425     return CreateFontIndirectA( &logfont );
426 }
427 
428 /*************************************************************************
429  *           CreateFontW    (GDI32.@)
430  */
431 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
432                               INT orient, INT weight, DWORD italic,
433                               DWORD underline, DWORD strikeout, DWORD charset,
434                               DWORD outpres, DWORD clippres, DWORD quality,
435                               DWORD pitch, LPCWSTR name )
436 {
437     LOGFONTW logfont;
438 
439     logfont.lfHeight = height;
440     logfont.lfWidth = width;
441     logfont.lfEscapement = esc;
442     logfont.lfOrientation = orient;
443     logfont.lfWeight = weight;
444     logfont.lfItalic = italic;
445     logfont.lfUnderline = underline;
446     logfont.lfStrikeOut = strikeout;
447     logfont.lfCharSet = charset;
448     logfont.lfOutPrecision = outpres;
449     logfont.lfClipPrecision = clippres;
450     logfont.lfQuality = quality;
451     logfont.lfPitchAndFamily = pitch;
452 
453     if (name)
454         lstrcpynW(logfont.lfFaceName, name,
455                   sizeof(logfont.lfFaceName) / sizeof(WCHAR));
456     else
457         logfont.lfFaceName[0] = '\0';
458 
459     return CreateFontIndirectW( &logfont );
460 }
461 
462 
463 /***********************************************************************
464  *           FONT_SelectObject
465  *
466  * If the driver supports vector fonts we create a gdi font first and
467  * then call the driver to give it a chance to supply its own device
468  * font.  If the driver wants to do this it returns TRUE and we can
469  * delete the gdi font, if the driver wants to use the gdi font it
470  * should return FALSE, to signal an error return GDI_ERROR.  For
471  * drivers that don't support vector fonts they must supply their own
472  * font.
473  */
474 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, HDC hdc )
475 {
476     HGDIOBJ ret = 0;
477     DC *dc = get_dc_ptr( hdc );
478 
479     if (!dc) return 0;
480 
481     if (!GDI_inc_ref_count( handle ))
482     {
483         release_dc_ptr( dc );
484         return 0;
485     }
486 
487     if (dc->hFont != handle || dc->gdiFont == NULL)
488     {
489         if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
490         {
491             FONTOBJ *font = GDI_GetObjPtr( handle, FONT_MAGIC );  /* to grab the GDI lock (FIXME) */
492             dc->gdiFont = WineEngCreateFontInstance(dc, handle);
493             if (font) GDI_ReleaseObj( handle );
494         }
495     }
496 
497     if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle, dc->gdiFont );
498 
499     if (ret && dc->gdiFont) dc->gdiFont = 0;
500 
501     if (ret == HGDI_ERROR)
502     {
503         GDI_dec_ref_count( handle );
504         ret = 0; /* SelectObject returns 0 on error */
505     }
506     else
507     {
508         ret = dc->hFont;
509         dc->hFont = handle;
510         GDI_dec_ref_count( ret );
511     }
512     release_dc_ptr( dc );
513     return ret;
514 }
515 
516 
517 /***********************************************************************
518  *           FONT_GetObjectA
519  */
520 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
521 {
522     FONTOBJ *font = obj;
523     LOGFONTA lfA;
524 
525     if(!buffer)
526         return sizeof(lfA);
527     FONT_LogFontWToA( &font->logfont, &lfA );
528 
529     if (count > sizeof(lfA)) count = sizeof(lfA);
530     memcpy( buffer, &lfA, count );
531     return count;
532 }
533 
534 /***********************************************************************
535  *           FONT_GetObjectW
536  */
537 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
538 {
539     FONTOBJ *font = obj;
540     if(!buffer)
541         return sizeof(LOGFONTW);
542     if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
543     memcpy( buffer, &font->logfont, count );
544     return count;
545 }
546 
547 
548 /***********************************************************************
549  *           FONT_DeleteObject
550  */
551 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
552 {
553     WineEngDestroyFontInstance( handle );
554     return GDI_FreeObject( handle, obj );
555 }
556 
557 
558 /***********************************************************************
559  *              FONT_EnumInstance
560  *
561  * Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
562  *       We have to use other types because of the FONTENUMPROCW definition.
563  */
564 static INT CALLBACK FONT_EnumInstance( const LOGFONTW *plf, const TEXTMETRICW *ptm,
565                                        DWORD fType, LPARAM lp )
566 {
567     fontEnum32 *pfe = (fontEnum32*)lp;
568     INT ret = 1;
569 
570     /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
571     if ((!pfe->lpLogFontParam ||
572         pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
573         pfe->lpLogFontParam->lfCharSet == plf->lfCharSet) &&
574        (!(fType & RASTER_FONTTYPE) || GetDeviceCaps(pfe->hdc, TEXTCAPS) & TC_RA_ABLE) )
575     {
576         /* convert font metrics */
577         ENUMLOGFONTEXA logfont;
578         NEWTEXTMETRICEXA tmA;
579 
580         pfe->dwFlags |= ENUM_CALLED;
581         if (!(pfe->dwFlags & ENUM_UNICODE))
582         {
583             FONT_EnumLogFontExWToA( (const ENUMLOGFONTEXW *)plf, &logfont);
584             FONT_NewTextMetricExWToA( (const NEWTEXTMETRICEXW *)ptm, &tmA );
585             plf = (LOGFONTW *)&logfont.elfLogFont;
586             ptm = (TEXTMETRICW *)&tmA;
587         }
588 
589         ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
590     }
591     return ret;
592 }
593 
594 /***********************************************************************
595  *              FONT_EnumFontFamiliesEx
596  */
597 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
598                                     FONTENUMPROCW efproc,
599                                     LPARAM lParam, DWORD dwUnicode)
600 {
601     INT ret = 1, ret2;
602     DC *dc = get_dc_ptr( hDC );
603     fontEnum32 fe32;
604     BOOL enum_gdi_fonts;
605 
606     if (!dc) return 0;
607 
608     if (plf)
609         TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
610             plf->lfCharSet);
611     fe32.lpLogFontParam = plf;
612     fe32.lpEnumFunc = efproc;
613     fe32.lpData = lParam;
614     fe32.dwFlags = dwUnicode;
615     fe32.hdc = hDC;
616 
617     enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
618 
619     if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
620     {
621         ret = 0;
622         goto done;
623     }
624 
625     if (enum_gdi_fonts)
626         ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
627     fe32.dwFlags &= ~ENUM_CALLED;
628     if (ret && dc->funcs->pEnumDeviceFonts) {
629         ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
630         if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
631             ret = ret2;
632     }
633  done:
634     release_dc_ptr( dc );
635     return ret;
636 }
637 
638 /***********************************************************************
639  *              EnumFontFamiliesExW     (GDI32.@)
640  */
641 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
642                                     FONTENUMPROCW efproc,
643                                     LPARAM lParam, DWORD dwFlags )
644 {
645     return  FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
646 }
647 
648 /***********************************************************************
649  *              EnumFontFamiliesExA     (GDI32.@)
650  */
651 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
652                                     FONTENUMPROCA efproc,
653                                     LPARAM lParam, DWORD dwFlags)
654 {
655     LOGFONTW lfW, *plfW;
656 
657     if (plf)
658     {
659         FONT_LogFontAToW( plf, &lfW );
660         plfW = &lfW;
661     }
662     else plfW = NULL;
663 
664     return FONT_EnumFontFamiliesEx( hDC, plfW, (FONTENUMPROCW)efproc, lParam, 0);
665 }
666 
667 /***********************************************************************
668  *              EnumFontFamiliesA       (GDI32.@)
669  */
670 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
671                                   FONTENUMPROCA efproc, LPARAM lpData )
672 {
673     LOGFONTA lf, *plf;
674 
675     if (lpFamily)
676     {
677         if (!*lpFamily) return 1;
678         lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
679         lf.lfCharSet = DEFAULT_CHARSET;
680         lf.lfPitchAndFamily = 0;
681         plf = &lf;
682     }
683     else plf = NULL;
684 
685     return EnumFontFamiliesExA( hDC, plf, efproc, lpData, 0 );
686 }
687 
688 /***********************************************************************
689  *              EnumFontFamiliesW       (GDI32.@)
690  */
691 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
692                                   FONTENUMPROCW efproc, LPARAM lpData )
693 {
694     LOGFONTW lf, *plf;
695 
696     if (lpFamily)
697     {
698         if (!*lpFamily) return 1;
699         lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
700         lf.lfCharSet = DEFAULT_CHARSET;
701         lf.lfPitchAndFamily = 0;
702         plf = &lf;
703     }
704     else plf = NULL;
705 
706     return EnumFontFamiliesExW( hDC, plf, efproc, lpData, 0 );
707 }
708 
709 /***********************************************************************
710  *              EnumFontsA              (GDI32.@)
711  */
712 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
713                            LPARAM lpData )
714 {
715     return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
716 }
717 
718 /***********************************************************************
719  *              EnumFontsW              (GDI32.@)
720  */
721 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
722                            LPARAM lpData )
723 {
724     return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
725 }
726 
727 
728 /***********************************************************************
729  *           GetTextCharacterExtra    (GDI32.@)
730  */
731 INT WINAPI GetTextCharacterExtra( HDC hdc )
732 {
733     INT ret;
734     DC *dc = get_dc_ptr( hdc );
735     if (!dc) return 0x80000000;
736     ret = dc->charExtra;
737     release_dc_ptr( dc );
738     return ret;
739 }
740 
741 
742 /***********************************************************************
743  *           SetTextCharacterExtra    (GDI32.@)
744  */
745 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
746 {
747     INT prev;
748     DC * dc = get_dc_ptr( hdc );
749     if (!dc) return 0x80000000;
750     if (dc->funcs->pSetTextCharacterExtra)
751         prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
752     else
753     {
754         prev = dc->charExtra;
755         dc->charExtra = extra;
756     }
757     release_dc_ptr( dc );
758     return prev;
759 }
760 
761 
762 /***********************************************************************
763  *           SetTextJustification    (GDI32.@)
764  */
765 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
766 {
767     BOOL ret = TRUE;
768     DC * dc = get_dc_ptr( hdc );
769     if (!dc) return FALSE;
770     if (dc->funcs->pSetTextJustification)
771         ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
772     else
773     {
774         extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
775         if (!extra) breaks = 0;
776         if (breaks)
777         {
778             dc->breakExtra = extra / breaks;
779             dc->breakRem   = extra - (breaks * dc->breakExtra);
780         }
781         else
782         {
783             dc->breakExtra = 0;
784             dc->breakRem   = 0;
785         }
786     }
787     release_dc_ptr( dc );
788     return ret;
789 }
790 
791 
792 /***********************************************************************
793  *           GetTextFaceA    (GDI32.@)
794  */
795 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
796 {
797     INT res = GetTextFaceW(hdc, 0, NULL);
798     LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
799     GetTextFaceW( hdc, res, nameW );
800 
801     if (name)
802     {
803         if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
804             name[count-1] = 0;
805         res = strlen(name);
806     }
807     else
808         res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
809     HeapFree( GetProcessHeap(), 0, nameW );
810     return res;
811 }
812 
813 /***********************************************************************
814  *           GetTextFaceW    (GDI32.@)
815  */
816 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
817 {
818     FONTOBJ *font;
819     INT     ret = 0;
820 
821     DC * dc = get_dc_ptr( hdc );
822     if (!dc) return 0;
823 
824     if(dc->gdiFont)
825         ret = WineEngGetTextFace(dc->gdiFont, count, name);
826     else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
827     {
828         if (name)
829         {
830             lstrcpynW( name, font->logfont.lfFaceName, count );
831             ret = strlenW(name);
832         }
833         else ret = strlenW(font->logfont.lfFaceName) + 1;
834         GDI_ReleaseObj( dc->hFont );
835     }
836     release_dc_ptr( dc );
837     return ret;
838 }
839 
840 
841 /***********************************************************************
842  *           GetTextExtentPoint32A    (GDI32.@)
843  *
844  * See GetTextExtentPoint32W.
845  */
846 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
847                                      LPSIZE size )
848 {
849     BOOL ret = FALSE;
850     INT wlen;
851     LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
852 
853     if (p) {
854         ret = GetTextExtentPoint32W( hdc, p, wlen, size );
855         HeapFree( GetProcessHeap(), 0, p );
856     }
857 
858     TRACE("(%p %s %d %p): returning %d x %d\n",
859           hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
860     return ret;
861 }
862 
863 
864 /***********************************************************************
865  * GetTextExtentPoint32W [GDI32.@]
866  *
867  * Computes width/height for a string.
868  *
869  * Computes width and height of the specified string.
870  *
871  * RETURNS
872  *    Success: TRUE
873  *    Failure: FALSE
874  */
875 BOOL WINAPI GetTextExtentPoint32W(
876     HDC hdc,     /* [in]  Handle of device context */
877     LPCWSTR str,   /* [in]  Address of text string */
878     INT count,   /* [in]  Number of characters in string */
879     LPSIZE size) /* [out] Address of structure for string size */
880 {
881     return GetTextExtentExPointW(hdc, str, count, 0, NULL, NULL, size);
882 }
883 
884 /***********************************************************************
885  * GetTextExtentExPointI [GDI32.@]
886  *
887  * Computes width and height of the array of glyph indices.
888  *
889  * PARAMS
890  *    hdc     [I] Handle of device context.
891  *    indices [I] Glyph index array.
892  *    count   [I] Number of glyphs in array.
893  *    max_ext [I] Maximum width in glyphs.
894  *    nfit    [O] Maximum number of characters.
895  *    dxs     [O] Partial string widths.
896  *    size    [O] Returned string size.
897  *
898  * RETURNS
899  *    Success: TRUE
900  *    Failure: FALSE
901  */
902 BOOL WINAPI GetTextExtentExPointI( HDC hdc, const WORD *indices, INT count, INT max_ext,
903                                    LPINT nfit, LPINT dxs, LPSIZE size )
904 {
905     BOOL ret = FALSE;
906     DC * dc = get_dc_ptr( hdc );
907     if (!dc) return FALSE;
908 
909     if(dc->gdiFont) {
910         ret = WineEngGetTextExtentExPointI(dc->gdiFont, indices, count, max_ext, nfit, dxs, size);
911         size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
912         size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
913         size->cx += count * dc->charExtra;
914     }
915     else if(dc->funcs->pGetTextExtentExPoint) {
916         FIXME("calling GetTextExtentExPoint\n");
917         ret = dc->funcs->pGetTextExtentExPoint( dc->physDev, (LPCWSTR)indices,
918                                                 count, max_ext, nfit, dxs, size );
919     }
920 
921     release_dc_ptr( dc );
922 
923     TRACE("(%p %p %d %p): returning %d x %d\n",
924           hdc, indices, count, size, size->cx, size->cy );
925     return ret;
926 }
927 
928 /***********************************************************************
929  * GetTextExtentPointI [GDI32.@]
930  *
931  * Computes width and height of the array of glyph indices.
932  *
933  * PARAMS
934  *    hdc     [I] Handle of device context.
935  *    indices [I] Glyph index array.
936  *    count   [I] Number of glyphs in array.
937  *    size    [O] Returned string size.
938  *
939  * RETURNS
940  *    Success: TRUE
941  *    Failure: FALSE
942  */
943 BOOL WINAPI GetTextExtentPointI( HDC hdc, const WORD *indices, INT count, LPSIZE size )
944 {
945     return GetTextExtentExPointI( hdc, indices, count, 0, NULL, NULL, size );
946 }
947 
948 
949 /***********************************************************************
950  *           GetTextExtentPointA    (GDI32.@)
951  */
952 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
953                                           LPSIZE size )
954 {
955     TRACE("not bug compatible.\n");
956     return GetTextExtentPoint32A( hdc, str, count, size );
957 }
958 
959 /***********************************************************************
960  *           GetTextExtentPointW   (GDI32.@)
961  */
962 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
963                                           LPSIZE size )
964 {
965     TRACE("not bug compatible.\n");
966     return GetTextExtentPoint32W( hdc, str, count, size );
967 }
968 
969 
970 /***********************************************************************
971  *           GetTextExtentExPointA    (GDI32.@)
972  */
973 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
974                                    INT maxExt, LPINT lpnFit,
975                                    LPINT alpDx, LPSIZE size )
976 {
977     BOOL ret;
978     INT wlen;
979     INT *walpDx = NULL;
980     LPWSTR p = NULL;
981     
982     if (alpDx &&
983        NULL == (walpDx = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT))))
984        return FALSE;
985     
986     p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
987     ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, walpDx, size);
988     if (walpDx)