Fix a couple of bugs in CDROM_GetSerial:
[wine] / objects / font.c
CommitLineData
401710d7
AJ
1/*
2 * GDI font objects
3 *
4 * Copyright 1993 Alexandre Julliard
23946ad2 5 * 1997 Alex Korobka
409374d9 6 * Copyright 2002,2003 Shachar Shemesh
0799c1a7
AJ
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7e56f684 21 */
401710d7 22
9aab47ed
PS
23#include "config.h"
24#include "wine/port.h"
25
401710d7 26#include <stdlib.h>
8d24ae6d 27#include <string.h>
814654ef 28#include <assert.h>
24a62ab9
AJ
29#include "winerror.h"
30#include "winnls.h"
28a632a8 31#include "wownt32.h"
9169729b 32#include "gdi.h"
d7b76822 33#include "wine/unicode.h"
0799c1a7 34#include "wine/debug.h"
401710d7 35
0799c1a7
AJ
36WINE_DEFAULT_DEBUG_CHANNEL(font);
37WINE_DECLARE_DEBUG_CHANNEL(gdi);
b4b9fae6 38
d8a9244f
AJ
39static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
40static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
41static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
43static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
44
45static const struct gdi_obj_funcs font_funcs =
46{
47 FONT_SelectObject, /* pSelectObject */
48 FONT_GetObject16, /* pGetObject16 */
49 FONT_GetObjectA, /* pGetObjectA */
50 FONT_GetObjectW, /* pGetObjectW */
51 NULL, /* pUnrealizeObject */
52 FONT_DeleteObject /* pDeleteObject */
53};
54
23946ad2 55#define ENUM_UNICODE 0x00000001
f879cb9e 56#define ENUM_CALLED 0x00000002
7ebe1a41 57
78b041cf
AJ
58typedef struct
59{
60 GDIOBJHDR header;
61 LOGFONTW logfont;
62} FONTOBJ;
63
23946ad2
AJ
64typedef struct
65{
66 LPLOGFONT16 lpLogFontParam;
c99c022a 67 FONTENUMPROC16 lpEnumFunc;
23946ad2 68 LPARAM lpData;
7ebe1a41 69
23946ad2
AJ
70 LPNEWTEXTMETRICEX16 lpTextMetric;
71 LPENUMLOGFONTEX16 lpLogFont;
72 SEGPTR segTextMetric;
73 SEGPTR segLogFont;
96ad51b3 74 DWORD dwFlags;
ab246a67
AJ
75 HDC hdc;
76 DC *dc;
77 PHYSDEV physDev;
23946ad2 78} fontEnum16;
7ebe1a41 79
23946ad2
AJ
80typedef struct
81{
a3960292 82 LPLOGFONTW lpLogFontParam;
c99c022a 83 FONTENUMPROCW lpEnumFunc;
2aa85eed 84 LPARAM lpData;
f879cb9e 85 DWORD dwFlags;
ab246a67
AJ
86 HDC hdc;
87 DC *dc;
88 PHYSDEV physDev;
23946ad2 89} fontEnum32;
9a624916 90
ab9e8bc9
DR
91/*
92 * For TranslateCharsetInfo
93 */
94#define FS(x) {{0,0,0,0},{0x1<<(x),0}}
95#define MAXTCIINDEX 32
96static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
97 /* ANSI */
98 { ANSI_CHARSET, 1252, FS(0)},
99 { EASTEUROPE_CHARSET, 1250, FS(1)},
100 { RUSSIAN_CHARSET, 1251, FS(2)},
101 { GREEK_CHARSET, 1253, FS(3)},
102 { TURKISH_CHARSET, 1254, FS(4)},
103 { HEBREW_CHARSET, 1255, FS(5)},
104 { ARABIC_CHARSET, 1256, FS(6)},
105 { BALTIC_CHARSET, 1257, FS(7)},
8da26fb2 106 { VIETNAMESE_CHARSET, 1258, FS(8)},
ab9e8bc9
DR
107 /* reserved by ANSI */
108 { DEFAULT_CHARSET, 0, FS(0)},
109 { DEFAULT_CHARSET, 0, FS(0)},
110 { DEFAULT_CHARSET, 0, FS(0)},
111 { DEFAULT_CHARSET, 0, FS(0)},
112 { DEFAULT_CHARSET, 0, FS(0)},
113 { DEFAULT_CHARSET, 0, FS(0)},
114 { DEFAULT_CHARSET, 0, FS(0)},
ab9e8bc9
DR
115 /* ANSI and OEM */
116 { THAI_CHARSET, 874, FS(16)},
117 { SHIFTJIS_CHARSET, 932, FS(17)},
118 { GB2312_CHARSET, 936, FS(18)},
119 { HANGEUL_CHARSET, 949, FS(19)},
120 { CHINESEBIG5_CHARSET, 950, FS(20)},
9a624916 121 { JOHAB_CHARSET, 1361, FS(21)},
ab9e8bc9
DR
122 /* reserved for alternate ANSI and OEM */
123 { DEFAULT_CHARSET, 0, FS(0)},
124 { DEFAULT_CHARSET, 0, FS(0)},
125 { DEFAULT_CHARSET, 0, FS(0)},
126 { DEFAULT_CHARSET, 0, FS(0)},
127 { DEFAULT_CHARSET, 0, FS(0)},
128 { DEFAULT_CHARSET, 0, FS(0)},
129 { DEFAULT_CHARSET, 0, FS(0)},
130 { DEFAULT_CHARSET, 0, FS(0)},
131 /* reserved for system */
132 { DEFAULT_CHARSET, 0, FS(0)},
8da26fb2 133 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
ab9e8bc9
DR
134};
135
401710d7 136/***********************************************************************
23946ad2 137 * LOGFONT conversion functions.
401710d7 138 */
aface537 139static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
21979019 140{
d1682aab
UW
141 font16->lfHeight = font32->lfHeight;
142 font16->lfWidth = font32->lfWidth;
143 font16->lfEscapement = font32->lfEscapement;
144 font16->lfOrientation = font32->lfOrientation;
145 font16->lfWeight = font32->lfWeight;
146 font16->lfItalic = font32->lfItalic;
147 font16->lfUnderline = font32->lfUnderline;
148 font16->lfStrikeOut = font32->lfStrikeOut;
149 font16->lfCharSet = font32->lfCharSet;
150 font16->lfOutPrecision = font32->lfOutPrecision;
151 font16->lfClipPrecision = font32->lfClipPrecision;
152 font16->lfQuality = font32->lfQuality;
153 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
24a62ab9
AJ
154 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
155 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
156 font16->lfFaceName[LF_FACESIZE-1] = 0;
21979019
AJ
157}
158
aface537 159static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
e2991ea7 160{
d1682aab
UW
161 font32->lfHeight = font16->lfHeight;
162 font32->lfWidth = font16->lfWidth;
163 font32->lfEscapement = font16->lfEscapement;
164 font32->lfOrientation = font16->lfOrientation;
165 font32->lfWeight = font16->lfWeight;
166 font32->lfItalic = font16->lfItalic;
167 font32->lfUnderline = font16->lfUnderline;
168 font32->lfStrikeOut = font16->lfStrikeOut;
169 font32->lfCharSet = font16->lfCharSet;
170 font32->lfOutPrecision = font16->lfOutPrecision;
171 font32->lfClipPrecision = font16->lfClipPrecision;
172 font32->lfQuality = font16->lfQuality;
173 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
24a62ab9
AJ
174 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
175 font32->lfFaceName[LF_FACESIZE-1] = 0;
21979019
AJ
176}
177
aface537 178static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
e6ab9d30 179{
2aa85eed
HD
180 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
181 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
182 LF_FACESIZE);
183}
184
aface537 185static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
2aa85eed
HD
186{
187 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
188 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
189 LF_FACESIZE, NULL, NULL);
190}
191
aface537 192static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
2aa85eed
HD
193{
194 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
195
196 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
197 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
198 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
199 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
200 font16->elfStyle, LF_FACESIZE, NULL, NULL );
201 font16->elfStyle[LF_FACESIZE-1] = '\0';
202 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
203 font16->elfScript, LF_FACESIZE, NULL, NULL );
204 font16->elfScript[LF_FACESIZE-1] = '\0';
205}
206
aface537 207static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
2aa85eed
HD
208{
209 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
210
211 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
212 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
213 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
214 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
215 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
216 fontA->elfStyle[LF_FACESIZE-1] = '\0';
217 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
218 fontA->elfScript, LF_FACESIZE, NULL, NULL );
219 fontA->elfScript[LF_FACESIZE-1] = '\0';
220}
221
21979019 222/***********************************************************************
23946ad2
AJ
223 * TEXTMETRIC conversion functions.
224 */
aface537 225static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
2aa85eed
HD
226{
227 ptmA->tmHeight = ptmW->tmHeight;
228 ptmA->tmAscent = ptmW->tmAscent;
229 ptmA->tmDescent = ptmW->tmDescent;
230 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
231 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
232 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
233 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
234 ptmA->tmWeight = ptmW->tmWeight;
235 ptmA->tmOverhang = ptmW->tmOverhang;
236 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
237 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
238 ptmA->tmFirstChar = ptmW->tmFirstChar;
239 ptmA->tmLastChar = ptmW->tmLastChar;
240 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
241 ptmA->tmBreakChar = ptmW->tmBreakChar;
242 ptmA->tmItalic = ptmW->tmItalic;
243 ptmA->tmUnderlined = ptmW->tmUnderlined;
244 ptmA->tmStruckOut = ptmW->tmStruckOut;
245 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
246 ptmA->tmCharSet = ptmW->tmCharSet;
247}
248
249
aface537
AJ
250static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
251{
252 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
253 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
254 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
255 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
256 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
257 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
258 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
259 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
260 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
261 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
262 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
263 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar;
264 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
265 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
266 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar;
267 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
268 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
269 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
270 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
271 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
26ee2ca4
HD
272 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
273 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
274 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
275 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
276 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
2aa85eed
HD
277}
278
ba9dc78e 279static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
2aa85eed
HD
280{
281 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
26ee2ca4
HD
282 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
283 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
284 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
285 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
286 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
2aa85eed
HD
287}
288
2aa85eed
HD
289/***********************************************************************
290 * CreateFontIndirectA (GDI32.@)
291 */
292HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
293{
294 LOGFONTW lfW;
295
296 if (plfA) {
297 FONT_LogFontAToW( plfA, &lfW );
298 return CreateFontIndirectW( &lfW );
299 } else
300 return CreateFontIndirectW( NULL );
301
302}
303
304/***********************************************************************
305 * CreateFontIndirectW (GDI32.@)
306 */
307HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
401710d7 308{
2a2321bb 309 HFONT hFont = 0;
0c126c7c 310
2aa85eed 311 if (plf)
ca22b33d 312 {
2aa85eed 313 FONTOBJ* fontPtr;
28a632a8
MS
314 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
315 (HGDIOBJ *)&hFont, &font_funcs )))
2a2321bb 316 {
2aa85eed 317 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
23946ad2 318
547cdc2b 319 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
9a624916 320 plf->lfHeight, plf->lfWidth,
2aa85eed 321 plf->lfEscapement, plf->lfOrientation,
74c2cbee 322 plf->lfPitchAndFamily,
bc710312
HD
323 plf->lfOutPrecision, plf->lfClipPrecision,
324 plf->lfQuality, plf->lfCharSet,
2aa85eed
HD
325 debugstr_w(plf->lfFaceName),
326 plf->lfWeight > 400 ? "Bold" : "",
327 plf->lfItalic ? "Italic" : "", hFont);
46ea8b3f 328
2aa85eed 329 if (plf->lfEscapement != plf->lfOrientation) {
46ea8b3f
AJ
330 /* this should really depend on whether GM_ADVANCED is set */
331 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
dd03cc19 332 WARN("orientation angle %f set to "
547cdc2b 333 "escapement angle %f for new font %p\n",
2aa85eed 334 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
46ea8b3f 335 }
2a2321bb 336 GDI_ReleaseObj( hFont );
23946ad2 337 }
ca22b33d 338 }
dd03cc19 339 else WARN("(NULL) => NULL\n");
401710d7 340
23946ad2
AJ
341 return hFont;
342}
401710d7 343
18f92e76 344/*************************************************************************
2aa85eed 345 * CreateFontA (GDI32.@)
18f92e76 346 */
a3960292
AJ
347HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
348 INT orient, INT weight, DWORD italic,
670cdc45
AJ
349 DWORD underline, DWORD strikeout, DWORD charset,
350 DWORD outpres, DWORD clippres, DWORD quality,
351 DWORD pitch, LPCSTR name )
18f92e76 352{
2aa85eed
HD
353 LOGFONTA logfont;
354
355 logfont.lfHeight = height;
356 logfont.lfWidth = width;
357 logfont.lfEscapement = esc;
358 logfont.lfOrientation = orient;
359 logfont.lfWeight = weight;
360 logfont.lfItalic = italic;
361 logfont.lfUnderline = underline;
362 logfont.lfStrikeOut = strikeout;
363 logfont.lfCharSet = charset;
364 logfont.lfOutPrecision = outpres;
365 logfont.lfClipPrecision = clippres;
366 logfont.lfQuality = quality;
367 logfont.lfPitchAndFamily = pitch;
9a624916
VB
368
369 if (name)
2aa85eed 370 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
9a624916 371 else
2aa85eed
HD
372 logfont.lfFaceName[0] = '\0';
373
374 return CreateFontIndirectA( &logfont );
18f92e76
AJ
375}
376
18f92e76 377/*************************************************************************
2aa85eed 378 * CreateFontW (GDI32.@)
18f92e76 379 */
a3960292
AJ
380HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
381 INT orient, INT weight, DWORD italic,
670cdc45
AJ
382 DWORD underline, DWORD strikeout, DWORD charset,
383 DWORD outpres, DWORD clippres, DWORD quality,
384 DWORD pitch, LPCWSTR name )
18f92e76 385{
2aa85eed
HD
386 LOGFONTW logfont;
387
388 logfont.lfHeight = height;
389 logfont.lfWidth = width;
390 logfont.lfEscapement = esc;
391 logfont.lfOrientation = orient;
392 logfont.lfWeight = weight;
393 logfont.lfItalic = italic;
394 logfont.lfUnderline = underline;
395 logfont.lfStrikeOut = strikeout;
396 logfont.lfCharSet = charset;
397 logfont.lfOutPrecision = outpres;
398 logfont.lfClipPrecision = clippres;
399 logfont.lfQuality = quality;
400 logfont.lfPitchAndFamily = pitch;
9a624916
VB
401
402 if (name)
403 lstrcpynW(logfont.lfFaceName, name,
2aa85eed 404 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
9a624916 405 else
2aa85eed
HD
406 logfont.lfFaceName[0] = '\0';
407
408 return CreateFontIndirectW( &logfont );
18f92e76
AJ
409}
410
411
d8a9244f
AJ
412/***********************************************************************
413 * FONT_SelectObject
414 *
415 * If the driver supports vector fonts we create a gdi font first and
416 * then call the driver to give it a chance to supply its own device
417 * font. If the driver wants to do this it returns TRUE and we can
418 * delete the gdi font, if the driver wants to use the gdi font it
419 * should return FALSE, to signal an error return GDI_ERROR. For
420 * drivers that don't support vector fonts they must supply their own
421 * font.
422 */
423static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
424{
425 HGDIOBJ ret = 0;
426 DC *dc = DC_GetDCPtr( hdc );
427
428 if (!dc) return 0;
429
430 if (dc->hFont != handle || dc->gdiFont == NULL)
431 {
432 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
433 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
434 }
435
436 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
437
438 if (ret && dc->gdiFont) dc->gdiFont = 0;
439
613ead7f 440 if (ret == HGDI_ERROR)
d8a9244f
AJ
441 ret = 0; /* SelectObject returns 0 on error */
442 else
443 {
444 ret = dc->hFont;
445 dc->hFont = handle;
446 }
447 GDI_ReleaseObj( hdc );
448 return ret;
449}
450
451
401710d7 452/***********************************************************************
0e270f45 453 * FONT_GetObject16
401710d7 454 */
d8a9244f 455static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
401710d7 456{
d8a9244f 457 FONTOBJ *font = obj;
2aa85eed
HD
458 LOGFONT16 lf16;
459
460 FONT_LogFontWTo16( &font->logfont, &lf16 );
461
d90840e1 462 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
2aa85eed 463 memcpy( buffer, &lf16, count );
401710d7
AJ
464 return count;
465}
466
0e270f45 467/***********************************************************************
aec373ca 468 * FONT_GetObjectA
0e270f45 469 */
d8a9244f 470static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
0e270f45 471{
d8a9244f 472 FONTOBJ *font = obj;
2aa85eed 473 LOGFONTA lfA;
0e270f45 474
2aa85eed 475 FONT_LogFontWToA( &font->logfont, &lfA );
0e270f45 476
2aa85eed 477 if (count > sizeof(lfA)) count = sizeof(lfA);
e9280a1e
MM
478 if(buffer)
479 memcpy( buffer, &lfA, count );
0e270f45
AJ
480 return count;
481}
d8a9244f 482
cba84884 483/***********************************************************************
aec373ca 484 * FONT_GetObjectW
cba84884 485 */
d8a9244f 486static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
cba84884 487{
d8a9244f 488 FONTOBJ *font = obj;
2aa85eed 489 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
e9280a1e
MM
490 if(buffer)
491 memcpy( buffer, &font->logfont, count );
cba84884
JS
492 return count;
493}
0e270f45
AJ
494
495
d8a9244f
AJ
496/***********************************************************************
497 * FONT_DeleteObject
498 */
499static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
500{
501 WineEngDestroyFontInstance( handle );
502 return GDI_FreeObject( handle, obj );
503}
504
505
23946ad2
AJ
506/***********************************************************************
507 * FONT_EnumInstance16
508 *
509 * Called by the device driver layer to pass font info
510 * down to the application.
511 */
ba9dc78e 512static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
2aa85eed 513 DWORD fType, LPARAM lp )
23946ad2 514{
ab246a67
AJ
515 fontEnum16 *pfe = (fontEnum16*)lp;
516 INT ret = 1;
517 DC *dc;
518
9a624916 519 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
23946ad2
AJ
520 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
521 {
7e92c9af
AJ
522 WORD args[7];
523 DWORD result;
524
2aa85eed
HD
525 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
526 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
96ad51b3 527 pfe->dwFlags |= ENUM_CALLED;
ab246a67
AJ
528 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
529
7e92c9af
AJ
530 args[6] = SELECTOROF(pfe->segLogFont);
531 args[5] = OFFSETOF(pfe->segLogFont);
532 args[4] = SELECTOROF(pfe->segTextMetric);
533 args[3] = OFFSETOF(pfe->segTextMetric);
534 args[2] = fType;
535 args[1] = HIWORD(pfe->lpData);
536 args[0] = LOWORD(pfe->lpData);
537 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
538 ret = LOWORD(result);
539
ab246a67
AJ
540 /* get the lock again and make sure the DC is still valid */
541 dc = DC_GetDCPtr( pfe->hdc );
542 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
543 {
544 if (dc) GDI_ReleaseObj( pfe->hdc );
545 pfe->hdc = 0; /* make sure we don't try to release it later on */
546 ret = 0;
547 }
23946ad2 548 }
ab246a67 549 return ret;
23946ad2
AJ
550}
551
552/***********************************************************************
aec373ca 553 * FONT_EnumInstance
23946ad2 554 */
ba9dc78e 555static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
2aa85eed 556 DWORD fType, LPARAM lp )
23946ad2 557{
ab246a67
AJ
558 fontEnum32 *pfe = (fontEnum32*)lp;
559 INT ret = 1;
560 DC *dc;
23946ad2 561
ab246a67 562 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
9a624916 563 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
23946ad2
AJ
564 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
565 {
566 /* convert font metrics */
ab246a67
AJ
567 ENUMLOGFONTEXA logfont;
568 NEWTEXTMETRICEXA tmA;
23946ad2 569
f879cb9e 570 pfe->dwFlags |= ENUM_CALLED;
ab246a67
AJ
571 if (!(pfe->dwFlags & ENUM_UNICODE))
572 {
573 FONT_EnumLogFontExWToA( plf, &logfont);
574 FONT_NewTextMetricExWToA( ptm, &tmA );
575 plf = (LPENUMLOGFONTEXW)&logfont;
ba9dc78e 576 ptm = (NEWTEXTMETRICEXW *)&tmA;
ab246a67
AJ
577 }
578 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
579
c99c022a 580 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
ab246a67
AJ
581
582 /* get the lock again and make sure the DC is still valid */
583 dc = DC_GetDCPtr( pfe->hdc );
584 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
585 {
586 if (dc) GDI_ReleaseObj( pfe->hdc );
587 pfe->hdc = 0; /* make sure we don't try to release it later on */
588 ret = 0;
589 }
23946ad2 590 }
ab246a67 591 return ret;
23946ad2
AJ
592}
593
594/***********************************************************************
19d66cc1 595 * EnumFontFamiliesEx (GDI.613)
23946ad2 596 */
670cdc45 597INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
c99c022a 598 FONTENUMPROC16 efproc, LPARAM lParam,
670cdc45 599 DWORD dwFlags)
23946ad2 600{
ab246a67 601 fontEnum16 fe16;
96ad51b3 602 INT16 ret = 1, ret2;
28a632a8 603 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
96ad51b3
HD
604 NEWTEXTMETRICEX16 tm16;
605 ENUMLOGFONTEX16 lf16;
606 LOGFONTW lfW;
607 BOOL enum_gdi_fonts;
2a2321bb
AJ
608
609 if (!dc) return 0;
96ad51b3
HD
610 FONT_LogFont16ToW(plf, &lfW);
611
28a632a8 612 fe16.hdc = HDC_32(hDC);
ab246a67
AJ
613 fe16.dc = dc;
614 fe16.physDev = dc->physDev;
96ad51b3
HD
615 fe16.lpLogFontParam = plf;
616 fe16.lpEnumFunc = efproc;
617 fe16.lpData = lParam;
618 fe16.lpTextMetric = &tm16;
619 fe16.lpLogFont = &lf16;
620 fe16.segTextMetric = MapLS( &tm16 );
621 fe16.segLogFont = MapLS( &lf16 );
622 fe16.dwFlags = 0;
623
624 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
625
626 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
23946ad2 627 {
96ad51b3
HD
628 ret = 0;
629 goto done;
23946ad2 630 }
96ad51b3
HD
631
632 if (enum_gdi_fonts)
633 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
634 fe16.dwFlags &= ~ENUM_CALLED;
635 if (ret && dc->funcs->pEnumDeviceFonts) {
636 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
637 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
638 ret = ret2;
639 }
640done:
641 UnMapLS( fe16.segTextMetric );
642 UnMapLS( fe16.segLogFont );
ab246a67 643 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
96ad51b3 644 return ret;
23946ad2
AJ
645}
646
647/***********************************************************************
aec373ca 648 * FONT_EnumFontFamiliesEx
23946ad2 649 */
2aa85eed 650static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
c99c022a 651 FONTENUMPROCW efproc,
2aa85eed 652 LPARAM lParam, DWORD dwUnicode)
23946ad2 653{
f879cb9e 654 INT ret = 1, ret2;
2a2321bb 655 DC *dc = DC_GetDCPtr( hDC );
814654ef
HD
656 fontEnum32 fe32;
657 BOOL enum_gdi_fonts;
2a2321bb
AJ
658
659 if (!dc) return 0;
23946ad2 660
f879cb9e
HD
661 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
662 plf->lfCharSet);
814654ef
HD
663 fe32.lpLogFontParam = plf;
664 fe32.lpEnumFunc = efproc;
665 fe32.lpData = lParam;
666 fe32.dwFlags = dwUnicode;
ab246a67
AJ
667 fe32.hdc = hDC;
668 fe32.dc = dc;
669 fe32.physDev = dc->physDev;
a9a671d7 670
814654ef 671 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
23946ad2 672
ab246a67
AJ
673 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
674 {
675 ret = 0;
676 goto done;
677 }
678
814654ef
HD
679 if (enum_gdi_fonts)
680 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
f879cb9e 681 fe32.dwFlags &= ~ENUM_CALLED;
ab246a67
AJ
682 if (ret && dc->funcs->pEnumDeviceFonts) {
683 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
f879cb9e
HD
684 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
685 ret = ret2;
686 }
ab246a67
AJ
687 done:
688 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
2a2321bb 689 return ret;
23946ad2
AJ
690}
691
692/***********************************************************************
2aa85eed 693 * EnumFontFamiliesExW (GDI32.@)
23946ad2 694 */
a3960292 695INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
c99c022a 696 FONTENUMPROCW efproc,
670cdc45 697 LPARAM lParam, DWORD dwFlags )
23946ad2 698{
e6ab9d30 699 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
23946ad2
AJ
700}
701
702/***********************************************************************
2aa85eed 703 * EnumFontFamiliesExA (GDI32.@)
23946ad2 704 */
a3960292 705INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
c99c022a 706 FONTENUMPROCA efproc,
670cdc45 707 LPARAM lParam, DWORD dwFlags)
23946ad2 708{
2aa85eed
HD
709 LOGFONTW lfW;
710 FONT_LogFontAToW( plf, &lfW );
711
c99c022a 712 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
23946ad2
AJ
713}
714
715/***********************************************************************
19d66cc1 716 * EnumFontFamilies (GDI.330)
23946ad2 717 */
670cdc45
AJ
718INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
719 FONTENUMPROC16 efproc, LPARAM lpData )
23946ad2
AJ
720{
721 LOGFONT16 lf;
722
723 lf.lfCharSet = DEFAULT_CHARSET;
a3960292 724 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
23946ad2
AJ
725 else lf.lfFaceName[0] = '\0';
726
ed29c905 727 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
23946ad2
AJ
728}
729
730/***********************************************************************
2aa85eed 731 * EnumFontFamiliesA (GDI32.@)
23946ad2 732 */
a3960292
AJ
733INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
734 FONTENUMPROCA efproc, LPARAM lpData )
23946ad2 735{
a3960292 736 LOGFONTA lf;
23946ad2
AJ
737
738 lf.lfCharSet = DEFAULT_CHARSET;
a3960292 739 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
23946ad2
AJ
740 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
741
c99c022a 742 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
23946ad2
AJ
743}
744
745/***********************************************************************
2aa85eed 746 * EnumFontFamiliesW (GDI32.@)
23946ad2 747 */
a3960292
AJ
748INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
749 FONTENUMPROCW efproc, LPARAM lpData )
23946ad2 750{
a3960292 751 LOGFONTW lf;
23946ad2
AJ
752
753 lf.lfCharSet = DEFAULT_CHARSET;
a3960292 754 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
23946ad2
AJ
755 else lf.lfFaceName[0] = 0;
756
c99c022a 757 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
23946ad2
AJ
758}
759
760/***********************************************************************
19d66cc1 761 * EnumFonts (GDI.70)
23946ad2 762 */
670cdc45
AJ
763INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
764 LPARAM lpData )
23946ad2 765{
c99c022a 766 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
23946ad2
AJ
767}
768
769/***********************************************************************
2aa85eed 770 * EnumFontsA (GDI32.@)
23946ad2 771 */
a3960292 772INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
670cdc45 773 LPARAM lpData )
23946ad2 774{
a3960292 775 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
23946ad2
AJ
776}
777
778/***********************************************************************
2aa85eed 779 * EnumFontsW (GDI32.@)
23946ad2 780 */
a3960292 781INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
670cdc45 782 LPARAM lpData )
23946ad2 783{
a3960292 784 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
23946ad2 785}
401710d7
AJ
786
787
401710d7 788/***********************************************************************
2aa85eed 789 * GetTextCharacterExtra (GDI32.@)
401710d7 790 */
a3960292 791INT WINAPI GetTextCharacterExtra( HDC hdc )
401710d7 792{
2a2321bb 793 INT ret;
2239abb9 794 DC *dc = DC_GetDCPtr( hdc );
bc710312
HD
795 if (!dc) return 0x80000000;
796 ret = dc->charExtra;
2a2321bb
AJ
797 GDI_ReleaseObj( hdc );
798 return ret;
7ebe1a41
AJ
799}
800
801
7ebe1a41 802/***********************************************************************
2aa85eed 803 * SetTextCharacterExtra (GDI32.@)
7ebe1a41 804 */
a3960292 805INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
7ebe1a41 806{
a3960292 807 INT prev;
7603deae 808 DC * dc = DC_GetDCPtr( hdc );
bc710312 809 if (!dc) return 0x80000000;
7603deae 810 if (dc->funcs->pSetTextCharacterExtra)
e21c15e3 811 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
2a2321bb
AJ
812 else
813 {
bc710312
HD
814 prev = dc->charExtra;
815 dc->charExtra = extra;
2a2321bb
AJ
816 }
817 GDI_ReleaseObj( hdc );
818 return prev;
401710d7
AJ
819}
820
821
7ebe1a41 822/***********************************************************************
2aa85eed 823 * SetTextJustification (GDI32.@)
7ebe1a41 824 */
a3960292 825BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
401710d7 826{
2a2321bb 827 BOOL ret = TRUE;
7603deae 828 DC * dc = DC_GetDCPtr( hdc );
2a2321bb 829 if (!dc) return FALSE;
7603deae 830 if (dc->funcs->pSetTextJustification)
e21c15e3 831 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
401710d7
AJ
832 else
833 {
2a2321bb
AJ
834 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
835 if (!extra) breaks = 0;
2239abb9
AJ
836 dc->breakTotalExtra = extra;
837 dc->breakCount = breaks;
2a2321bb
AJ
838 if (breaks)
839 {
2239abb9
AJ
840 dc->breakExtra = extra / breaks;
841 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
2a2321bb
AJ
842 }
843 else
844 {
2239abb9
AJ
845 dc->breakExtra = 0;
846 dc->breakRem = 0;
2a2321bb 847 }
401710d7 848 }
2a2321bb
AJ
849 GDI_ReleaseObj( hdc );
850 return ret;
401710d7
AJ
851}
852
7ebe1a41 853
aca05783 854/***********************************************************************
2aa85eed 855 * GetTextFaceA (GDI32.@)
aca05783 856 */
a3960292 857INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
2aa85eed
HD
858{
859 INT res = GetTextFaceW(hdc, 0, NULL);
860 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
861 GetTextFaceW( hdc, res, nameW );
9a624916 862
2aa85eed 863 if (name)
33c2ad57
AJ
864 {
865 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
866 name[count-1] = 0;
867 res = strlen(name);
868 }
2aa85eed
HD
869 else
870 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
871 HeapFree( GetProcessHeap(), 0, nameW );
872 return res;
873}
874
875/***********************************************************************
876 * GetTextFaceW (GDI32.@)
877 */
878INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
aca05783
AJ
879{
880 FONTOBJ *font;
2a2321bb 881 INT ret = 0;
aca05783 882
2239abb9 883 DC * dc = DC_GetDCPtr( hdc );
aca05783 884 if (!dc) return 0;
2a2321bb 885
8da26fb2
HD
886 if(dc->gdiFont)
887 ret = WineEngGetTextFace(dc->gdiFont, count, name);
888 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
2a2321bb
AJ
889 {
890 if (name)
891 {
2aa85eed
HD
892 lstrcpynW( name, font->logfont.lfFaceName, count );
893 ret = strlenW(name);
2a2321bb 894 }
2aa85eed 895 else ret = strlenW(font->logfont.lfFaceName) + 1;
2239abb9 896 GDI_ReleaseObj( dc->hFont );
2a2321bb
AJ
897 }
898 GDI_ReleaseObj( hdc );
899 return ret;
aca05783
AJ
900}
901
902
e2bfa4c7 903/***********************************************************************
2aa85eed 904 * GetTextExtentPoint32A (GDI32.@)
e2bfa4c7 905 */
a3960292
AJ
906BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
907 LPSIZE size )
401710d7 908{
7901c0b5 909 BOOL ret = FALSE;
2938242b
HD
910 INT wlen;
911 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
e2905ea4 912
814654ef 913 if (p) {
814654ef
HD
914 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
915 HeapFree( GetProcessHeap(), 0, p );
7901c0b5 916 }
814654ef 917
547cdc2b 918 TRACE("(%p %s %d %p): returning %ld x %ld\n",
7901c0b5 919 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
c553924d 920 return ret;
401710d7
AJ
921}
922
923
e2bfa4c7 924/***********************************************************************
2aa85eed 925 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
c7c217b3
AJ
926 *
927 * Computes width and height of the specified string.
928 *
929 * RETURNS
930 * Success: TRUE
931 * Failure: FALSE
e2bfa4c7 932 */
a3960292
AJ
933BOOL WINAPI GetTextExtentPoint32W(
934 HDC hdc, /* [in] Handle of device context */
c7c217b3 935 LPCWSTR str, /* [in] Address of text string */
a3960292
AJ
936 INT count, /* [in] Number of characters in string */
937 LPSIZE size) /* [out] Address of structure for string size */
e2bfa4c7 938{
2a2321bb 939 BOOL ret = FALSE;
c553924d 940 DC * dc = DC_GetDCPtr( hdc );
814654ef
HD
941 if (!dc) return FALSE;
942
5b01b506 943 if(dc->gdiFont) {
814654ef 944 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
5b01b506
HD
945 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
946 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
947 }
814654ef 948 else if(dc->funcs->pGetTextExtentPoint)
e21c15e3 949 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
814654ef
HD
950
951 GDI_ReleaseObj( hdc );
952
547cdc2b 953 TRACE("(%p %s %d %p): returning %ld x %ld\n",
c553924d 954 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
2a2321bb 955 return ret;
e2bfa4c7
AJ
956}
957
5b01b506
HD
958/***********************************************************************
959 * GetTextExtentPointI [GDI32.@]
960 *
961 * Computes width and height of the array of glyph indices.
962 *
963 * RETURNS
964 * Success: TRUE
965 * Failure: FALSE
966 */
967BOOL WINAPI GetTextExtentPointI(
968 HDC hdc, /* [in] Handle of device context */
969 const WORD *indices, /* [in] Address of glyph index array */
970 INT count, /* [in] Number of glyphs in array */
971 LPSIZE size) /* [out] Address of structure for string size */
972{
973 BOOL ret = FALSE;
974 DC * dc = DC_GetDCPtr( hdc );
975 if (!dc) return FALSE;
976
977 if(dc->gdiFont) {
978 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
979 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
980 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
981 }
982 else if(dc->funcs->pGetTextExtentPoint) {
983 FIXME("calling GetTextExtentPoint\n");
ce73456d 984 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
5b01b506
HD
985 }
986
987 GDI_ReleaseObj( hdc );
988
547cdc2b 989 TRACE("(%p %p %d %p): returning %ld x %ld\n",
5b01b506
HD
990 hdc, indices, count, size, size->cx, size->cy );
991 return ret;
992}
993
23946ad2 994
7e6ae4ba 995/***********************************************************************
2aa85eed 996 * GetTextExtentPointA (GDI32.@)
7e6ae4ba 997 */
a3960292
AJ
998BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
999 LPSIZE size )
7e6ae4ba 1000{
dd03cc19 1001 TRACE("not bug compatible.\n");
7e6ae4ba
AJ
1002 return GetTextExtentPoint32A( hdc, str, count, size );
1003}
1004
1005/***********************************************************************
2aa85eed 1006 * GetTextExtentPointW (GDI32.@)
7e6ae4ba 1007 */
a3960292
AJ
1008BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1009 LPSIZE size )
7e6ae4ba 1010{
dd03cc19 1011 TRACE("not bug compatible.\n");
7e6ae4ba
AJ
1012 return GetTextExtentPoint32W( hdc, str, count, size );
1013}
1014
e2bfa4c7 1015
b1bac320 1016/***********************************************************************
2aa85eed 1017 * GetTextExtentExPointA (GDI32.@)
b1bac320 1018 */
a3960292 1019BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
c553924d
HD
1020 INT maxExt, LPINT lpnFit,
1021 LPINT alpDx, LPSIZE size )
1022{
c553924d 1023 BOOL ret;
2938242b
HD
1024 INT wlen;
1025 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1026 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
c553924d
HD
1027 HeapFree( GetProcessHeap(), 0, p );
1028 return ret;
1029}
1030
1031
1032/***********************************************************************
2aa85eed 1033 * GetTextExtentExPointW (GDI32.@)
06a49f67
BM
1034 *
1035 * Return the size of the string as it would be if it was output properly by
1036 * e.g. TextOut.
1037 *
1038 * This should include
1039 * - Intercharacter spacing
1040 * - justification spacing (not yet done)
1041 * - kerning? see below
1042 *
1043 * Kerning. Since kerning would be carried out by the rendering code it should
9a624916 1044 * be done by the driver. However they don't support it yet. Also I am not
06a49f67
BM
1045 * yet persuaded that (certainly under Win95) any kerning is actually done.
1046 *
1047 * str: According to MSDN this should be null-terminated. That is not true; a
1048 * null will not terminate it early.
1049 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1050 * than count. I have seen it be either the size of the full string or
1051 * 1 less than the size of the full string. I have not seen it bear any
1052 * resemblance to the portion that would fit.
1053 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1054 * trailing intercharacter spacing and any trailing justification.
1055 *
1056 * FIXME
1057 * Currently we do this by measuring each character etc. We should do it by
1058 * passing the request to the driver, perhaps by extending the
1059 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1060 * thinking about kerning issues and rounding issues in the justification.
c553924d
HD
1061 */
1062
1063BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1064 INT maxExt, LPINT lpnFit,
1065 LPINT alpDx, LPSIZE size )
b1bac320 1066{
23946ad2 1067 int index, nFit, extent;
a3960292 1068 SIZE tSize;
2a2321bb 1069 BOOL ret = FALSE;
b1bac320 1070
547cdc2b 1071 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
551586e9 1072
23946ad2
AJ
1073 size->cx = size->cy = nFit = extent = 0;
1074 for(index = 0; index < count; index++)
b1bac320 1075 {
814654ef 1076 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
06a49f67
BM
1077 /* GetTextExtentPoint includes intercharacter spacing. */
1078 /* FIXME - justification needs doing yet. Remember that the base
1079 * data will not be in logical coordinates.
1080 */
2bbca90c
TM
1081 extent += tSize.cx;
1082 if( !lpnFit || extent <= maxExt )
06a49f67 1083 /* It is allowed to be equal. */
23946ad2 1084 {
23946ad2 1085 nFit++;
23946ad2 1086 if( alpDx ) alpDx[index] = extent;
23946ad2 1087 }
2bbca90c
TM
1088 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1089 str++;
b1bac320 1090 }
23946ad2 1091 size->cx = extent;
96cda944 1092 if(lpnFit) *lpnFit = nFit;
2a2321bb 1093 ret = TRUE;
23946ad2 1094
551586e9 1095 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1b490b42 1096
2a2321bb 1097done:
2a2321bb 1098 return ret;
b1bac320
AJ
1099}
1100
01d6346a 1101/***********************************************************************
2aa85eed 1102 * GetTextMetricsA (GDI32.@)
01d6346a 1103 */
a3960292 1104BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
39f54283
HD
1105{
1106 TEXTMETRICW tm32;
1107
1108 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1109 FONT_TextMetricWToA( &tm32, metrics );
1110 return TRUE;
1111}
1112
1113/***********************************************************************
1114 * GetTextMetricsW (GDI32.@)
1115 */
1116BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1117{
2a2321bb
AJ
1118 BOOL ret = FALSE;
1119 DC * dc = DC_GetDCPtr( hdc );
1120 if (!dc) return FALSE;
77b9918e 1121
814654ef
HD
1122 if (dc->gdiFont)
1123 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1124 else if (dc->funcs->pGetTextMetrics)
e21c15e3 1125 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
814654ef
HD
1126
1127 if (ret)
2a2321bb 1128 {
77b9918e
AJ
1129 /* device layer returns values in device units
1130 * therefore we have to convert them to logical */
1131
670cdc45 1132#define WDPTOLP(x) ((x<0)? \
8da26fb2
HD
1133 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1134 (abs(INTERNAL_XDSTOWS(dc, (x)))))
670cdc45 1135#define HDPTOLP(y) ((y<0)? \
8da26fb2
HD
1136 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1137 (abs(INTERNAL_YDSTOWS(dc, (y)))))
9a624916 1138
670cdc45
AJ
1139 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1140 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1141 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1142 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1143 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1144 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1145 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1146 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
2a2321bb 1147 ret = TRUE;
409000c3
HD
1148#undef WDPTOLP
1149#undef HDPTOLP
dd03cc19 1150 TRACE("text metrics:\n"
39f54283
HD
1151 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1152 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1153 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1154 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
dd03cc19
DP
1155 " PitchAndFamily = %02x\n"
1156 " --------------------\n"
1157 " InternalLeading = %li\n"
1158 " Ascent = %li\n"
1159 " Descent = %li\n"
1160 " Height = %li\n",
1161 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1162 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1163 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1164 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1165 metrics->tmPitchAndFamily,
1166 metrics->tmInternalLeading,
1167 metrics->tmAscent,
1168 metrics->tmDescent,
1169 metrics->tmHeight );
2a2321bb
AJ
1170 }
1171 GDI_ReleaseObj( hdc );
1172 return ret;
3051b644
AJ
1173}
1174
1175
c7c217b3 1176/***********************************************************************
17fd4e38 1177 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
c7c217b3
AJ
1178 *
1179 * NOTES
1180 * lpOTM should be LPOUTLINETEXTMETRIC
1181 *
1182 * RETURNS
1183 * Success: Non-zero or size of required buffer
1184 * Failure: 0
1185 */
85ed45e3 1186UINT16 WINAPI GetOutlineTextMetrics16(
c7c217b3 1187 HDC16 hdc, /* [in] Handle of device context */
85ed45e3 1188 UINT16 cbData, /* [in] Size of metric data array */
4a150e77 1189 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
c7c217b3 1190{
dd03cc19 1191 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
c7c217b3
AJ
1192 return 0;
1193}
1194
1195
4a150e77 1196/***********************************************************************
2aa85eed
HD
1197 * GetOutlineTextMetricsA (GDI32.@)
1198 * Gets metrics for TrueType fonts.
4a150e77
MV
1199 *
1200 *
1201 * RETURNS
1202 * Success: Non-zero or size of required buffer
1203 * Failure: 0
1204 */
a3960292
AJ
1205UINT WINAPI GetOutlineTextMetricsA(
1206 HDC hdc, /* [in] Handle of device context */
1207 UINT cbData, /* [in] Size of metric data array */
1208 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
4a150e77 1209{
814654ef
HD
1210 char buf[512], *ptr;
1211 UINT ret, needed;
1212 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1213 INT left, len;
4a150e77 1214
814654ef
HD
1215 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1216 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1217 return 0;
1218 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1219 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1220 }
4a150e77 1221
814654ef
HD
1222 needed = sizeof(OUTLINETEXTMETRICA);
1223 if(lpOTMW->otmpFamilyName)
1224 needed += WideCharToMultiByte(CP_ACP, 0,
9a624916 1225 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
814654ef
HD
1226 NULL, 0, NULL, NULL);
1227 if(lpOTMW->otmpFaceName)
1228 needed += WideCharToMultiByte(CP_ACP, 0,
9a624916 1229 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
814654ef
HD
1230 NULL, 0, NULL, NULL);
1231 if(lpOTMW->otmpStyleName)
1232 needed += WideCharToMultiByte(CP_ACP, 0,
9a624916 1233 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
814654ef
HD
1234 NULL, 0, NULL, NULL);
1235 if(lpOTMW->otmpFullName)
1236 needed += WideCharToMultiByte(CP_ACP, 0,
9a624916 1237 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
814654ef
HD
1238 NULL, 0, NULL, NULL);
1239
1240 if(!lpOTM) {
1241 ret = needed;
1242 goto end;
1243 }
4a150e77 1244
814654ef
HD
1245 if(needed > cbData) {
1246 ret = 0;
1247 goto end;
1248 }
4a150e77
MV
1249
1250
814654ef
HD
1251 lpOTM->otmSize = needed;
1252 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1253 lpOTM->otmFiller = 0;
1254 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1255 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1256 lpOTM->otmfsType = lpOTMW->otmfsType;
1257 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1258 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1259 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1260 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1261 lpOTM->otmAscent = lpOTMW->otmAscent;
1262 lpOTM->otmDescent = lpOTMW->otmDescent;
1263 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1264 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1265 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1266 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1267 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1268 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1269 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1270 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1271 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1272 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1273 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1274 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1275 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1276 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1277 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1278 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1279
1280
1281 ptr = (char*)(lpOTM + 1);
1282 left = needed - sizeof(*lpOTM);
1283
1284 if(lpOTMW->otmpFamilyName) {
1285 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1286 len = WideCharToMultiByte(CP_ACP, 0,
9a624916 1287 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
814654ef
HD
1288 ptr, left, NULL, NULL);
1289 left -= len;
1290 ptr += len;
4a150e77 1291 } else
814654ef
HD
1292 lpOTM->otmpFamilyName = 0;
1293
1294 if(lpOTMW->otmpFaceName) {
1295 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1296 len = WideCharToMultiByte(CP_ACP, 0,
9a624916 1297 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
814654ef
HD
1298 ptr, left, NULL, NULL);
1299 left -= len;
1300 ptr += len;
4a150e77 1301 } else
814654ef
HD
1302 lpOTM->otmpFaceName = 0;
1303
1304 if(lpOTMW->otmpStyleName) {
1305 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1306 len = WideCharToMultiByte(CP_ACP, 0,
9a624916 1307 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
814654ef
HD
1308 ptr, left, NULL, NULL);
1309 left -= len;
1310 ptr += len;
1311 } else
1312 lpOTM->otmpStyleName = 0;
1313
1314 if(lpOTMW->otmpFullName) {
1315 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1316 len = WideCharToMultiByte(CP_ACP, 0,
9a624916 1317 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
814654ef
HD
1318 ptr, left, NULL, NULL);
1319 left -= len;
1320 } else
1321 lpOTM->otmpFullName = 0;
9a624916 1322
814654ef 1323 assert(left == 0);
9a624916 1324
814654ef
HD
1325 ret = needed;
1326
1327end:
1328 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1329 HeapFree(GetProcessHeap(), 0, lpOTMW);
1330
1331 return ret;
4a150e77
MV
1332}
1333
814654ef 1334
0c0e3beb 1335/***********************************************************************
2aa85eed 1336 * GetOutlineTextMetricsW [GDI32.@]
0c0e3beb 1337 */
a3960292
AJ
1338UINT WINAPI GetOutlineTextMetricsW(
1339 HDC hdc, /* [in] Handle of device context */
1340 UINT cbData, /* [in] Size of metric data array */
1341 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
0c0e3beb 1342{
814654ef
HD
1343 DC *dc = DC_GetDCPtr( hdc );
1344 UINT ret;
1345
547cdc2b 1346 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
814654ef
HD
1347 if(!dc) return 0;
1348
409000c3 1349 if(dc->gdiFont) {
814654ef 1350 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
409000c3
HD
1351 if(ret && ret <= cbData) {
1352#define WDPTOLP(x) ((x<0)? \
1353 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1354 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1355#define HDPTOLP(y) ((y<0)? \
1356 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1357 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1358
1359 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1360 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1361 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1362 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1363 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1364 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1365 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1366 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1367 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1368 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1369 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1370 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1371 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1372 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1373 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1374 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1375 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1376 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1377 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1378 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1379 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1380 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1381 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1382 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1383 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1384 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1385 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1386 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1387 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1388 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1389 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1390 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1391#undef WDPTOLP
1392#undef HDPTOLP
1393 }
1394 }
814654ef
HD
1395
1396 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1397 but really this should just be a return 0. */
1398
1399 ret = sizeof(*lpOTM);
1400 if (lpOTM) {
1401 if(cbData < ret)
1402 ret = 0;
1403 else {
1404 memset(lpOTM, 0, ret);
1405 lpOTM->otmSize = sizeof(*lpOTM);
1406 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1407 /*
1408 Further fill of the structure not implemented,
1409 Needs real values for the structure members
1410 */
1411 }
1412 }
1413 }
1414 GDI_ReleaseObj(hdc);
1415 return ret;
0c0e3beb 1416}
4a150e77 1417
814654ef 1418
7ebe1a41 1419/***********************************************************************
3f8e407d
DT
1420 * GetCharWidthW (GDI32.@)
1421 * GetCharWidth32W (GDI32.@)
0e607784 1422 */
3f8e407d 1423BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
a3960292 1424 LPINT buffer )
0e607784 1425{
a3960292 1426 UINT i, extra;
2a2321bb
AJ
1427 BOOL ret = FALSE;
1428 DC * dc = DC_GetDCPtr( hdc );
1429 if (!dc) return FALSE;
33072e1f 1430
814654ef
HD
1431 if (dc->gdiFont)
1432 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1433 else if (dc->funcs->pGetCharWidth)
e21c15e3 1434 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
814654ef
HD
1435
1436 if (ret)
2a2321bb
AJ
1437 {
1438 /* convert device units to logical */
33072e1f 1439
2a2321bb
AJ
1440 extra = dc->vportExtX >> 1;
1441 for( i = firstChar; i <= lastChar; i++, buffer++ )
1442 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1443 ret = TRUE;
1444 }
1445 GDI_ReleaseObj( hdc );
1446 return ret;
0e607784 1447}
5819953c 1448
3ed37e08 1449
7ebe1a41 1450/***********************************************************************
3f8e407d
DT
1451 * GetCharWidthA (GDI32.@)
1452 * GetCharWidth32A (GDI32.@)
7ebe1a41 1453 */
3f8e407d 1454BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
a3960292 1455 LPINT buffer )
7ebe1a41 1456{
3f8e407d
DT
1457 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1458 LPSTR str;
1459 LPWSTR wstr;
1460 BOOL ret = TRUE;
1461
1462 if(count <= 0) return FALSE;
9a624916 1463
3f8e407d
DT
1464 str = HeapAlloc(GetProcessHeap(), 0, count);
1465 for(i = 0; i < count; i++)
1466 str[i] = (BYTE)(firstChar + i);
1467
1468 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1469
1470 for(i = 0; i < wlen; i++)
1471 {
1472 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1473 {
1474 ret = FALSE;
1475 break;
1476 }
1477 buffer++;
1478 }
1479
1480 HeapFree(GetProcessHeap(), 0, str);
1481 HeapFree(GetProcessHeap(), 0, wstr);
1482
1483 return ret;
7ebe1a41
AJ
1484}
1485
1486
54fe8380 1487/* FIXME: all following APIs ******************************************/
9a624916 1488
23946ad2 1489
21979019 1490/***********************************************************************
2aa85eed 1491 * SetMapperFlags (GDI32.@)
3ed37e08 1492 */
a3960292 1493DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
3ed37e08 1494{
7603deae 1495 DC *dc = DC_GetDCPtr( hDC );
9a624916 1496 DWORD ret = 0;
7603deae
HD
1497 if(!dc) return 0;
1498 if(dc->funcs->pSetMapperFlags)
e21c15e3 1499 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
7603deae 1500 else
547cdc2b 1501 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
2a2321bb 1502 GDI_ReleaseObj( hDC );
7603deae 1503 return ret;
3ed37e08
AJ
1504}
1505
670cdc45 1506/***********************************************************************
17fd4e38 1507 * GetAspectRatioFilterEx (GDI.486)
670cdc45 1508 */
85ed45e3 1509BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
670cdc45 1510{
dd03cc19 1511 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
670cdc45
AJ
1512 return FALSE;
1513}
1514
1beaae5f 1515/***********************************************************************
2aa85eed 1516 * GetAspectRatioFilterEx (GDI32.@)
1beaae5f 1517 */
a3960292 1518BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1beaae5f 1519{
547cdc2b 1520 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1beaae5f
PQ
1521 return FALSE;
1522}
3ed37e08 1523
21979019
AJ
1524
1525/***********************************************************************
2aa85eed 1526 * GetCharABCWidthsA (GDI32.@)
21979019 1527 */
a3960292
AJ
1528BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1529 LPABC abc )
21979019 1530{
18d7573c
AJ
1531 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1532 LPSTR str;
1533 LPWSTR wstr;
1534 BOOL ret = TRUE;
1535
1536 if(count <= 0) return FALSE;
9a624916 1537
18d7573c
AJ
1538 str = HeapAlloc(GetProcessHeap(), 0, count);
1539 for(i = 0; i < count; i++)
1540 str[i] = (BYTE)(firstChar + i);
1541
1542 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1543
1544 for(i = 0; i < wlen; i++)
1545 {
1546 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1547 {
1548 ret = FALSE;
1549 break;
1550 }
1551 abc++;
1552 }
1553
1554 HeapFree(GetProcessHeap(), 0, str);
1555 HeapFree(GetProcessHeap(), 0, wstr);
1556
1557 return ret;
21979019
AJ
1558}
1559
1560
46ea8b3f 1561/******************************************************************************
2aa85eed 1562 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
46ea8b3f
AJ
1563 *
1564 * PARAMS
1565 * hdc [I] Handle of device context
1566 * firstChar [I] First character in range to query
1567 * lastChar [I] Last character in range to query
1568 * abc [O] Address of character-width structure
1569 *
1570 * NOTES
1571 * Only works with TrueType fonts
1572 *
1573 * RETURNS
1574 * Success: TRUE
1575 * Failure: FALSE
21979019 1576 */
a3960292
AJ
1577BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1578 LPABC abc )
3ed37e08 1579{
18d7573c 1580 DC *dc = DC_GetDCPtr(hdc);
67f0be15 1581 int i;
18d7573c
AJ
1582 GLYPHMETRICS gm;
1583 BOOL ret = FALSE;
67f0be15 1584
18d7573c
AJ
1585 if(dc->gdiFont) {
1586 for (i=firstChar;i<=lastChar;i++) {
1587 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1588 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1589 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1590 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1591 }
1592 ret = TRUE;
67f0be15 1593 }
18d7573c
AJ
1594 GDI_ReleaseObj(hdc);
1595 return ret;
3ed37e08
AJ
1596}
1597
21979019
AJ
1598
1599/***********************************************************************
17fd4e38 1600 * GetGlyphOutline (GDI.309)
21979019 1601 */
670cdc45
AJ
1602DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1603 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1604 LPVOID lpBuffer, const MAT2 *lpmat2 )
21979019 1605{
dd03cc19 1606 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
54c2711f 1607 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
23946ad2 1608 return (DWORD)-1; /* failure */
1f57929b
AJ
1609}
1610
73450d65 1611
23946ad2 1612/***********************************************************************
2aa85eed 1613 * GetGlyphOutlineA (GDI32.@)
da0cfb36 1614 */
a3960292
AJ
1615DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1616 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
670cdc45 1617 LPVOID lpBuffer, const MAT2 *lpmat2 )
da0cfb36 1618{
18d7573c
AJ
1619 LPWSTR p = NULL;
1620 DWORD ret;
1621 UINT c;
1622
1623 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1624 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1625 c = p[0];
1626 } else
1627 c = uChar;
1628 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1629 lpmat2);
1630 if(p)
1631 HeapFree(GetProcessHeap(), 0, p);
1632 return ret;
da0cfb36
AJ
1633}
1634
23946ad2 1635/***********************************************************************
2aa85eed 1636 * GetGlyphOutlineW (GDI32.@)
da0cfb36 1637 */
a3960292
AJ
1638DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1639 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
670cdc45 1640 LPVOID lpBuffer, const MAT2 *lpmat2 )
da0cfb36 1641{
814654ef
HD
1642 DC *dc = DC_GetDCPtr(hdc);
1643 DWORD ret;
1644
547cdc2b 1645 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
54c2711f 1646 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
814654ef
HD
1647
1648 if(!dc) return GDI_ERROR;
1649
1650 if(dc->gdiFont)
1651 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1652 cbBuffer, lpBuffer, lpmat2);
1653 else
1654 ret = GDI_ERROR;
1655
1656 GDI_ReleaseObj(hdc);
1657 return ret;
da0cfb36 1658}
73450d65 1659
da0cfb36 1660
23946ad2 1661/***********************************************************************
2aa85eed 1662 * CreateScalableFontResourceA (GDI32.@)
da0cfb36 1663 */
a3960292 1664BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
670cdc45
AJ
1665 LPCSTR lpszResourceFile,
1666 LPCSTR lpszFontFile,
1667 LPCSTR lpszCurrentPath )
da0cfb36 1668{
e1ae23e0
LU
1669 HANDLE f;
1670
23946ad2
AJ
1671 /* fHidden=1 - only visible for the calling app, read-only, not
1672 * enumbered with EnumFonts/EnumFontFamilies
1673 * lpszCurrentPath can be NULL
1674 */
dd03cc19 1675 FIXME("(%ld,%s,%s,%s): stub\n",
b60c4ce0
FG
1676 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1677 debugstr_a(lpszCurrentPath) );
e1ae23e0
LU
1678
1679 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1680 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1681 CloseHandle(f);
1682 SetLastError(ERROR_FILE_EXISTS);
1683 return FALSE;
1684 }
23946ad2 1685 return FALSE; /* create failed */
da0cfb36
AJ
1686}
1687
23946ad2 1688/***********************************************************************
2aa85eed 1689 * CreateScalableFontResourceW (GDI32.@)
da0cfb36 1690 */
a3960292 1691BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
670cdc45
AJ
1692 LPCWSTR lpszResourceFile,
1693 LPCWSTR lpszFontFile,
1694 LPCWSTR lpszCurrentPath )
da0cfb36 1695{
dd03cc19 1696 FIXME("(%ld,%p,%p,%p): stub\n",
54c2711f 1697 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
23946ad2 1698 return FALSE; /* create failed */
75d86e1f
AJ
1699}
1700
1701
21979019 1702/*************************************************************************
2aa85eed 1703 * GetRasterizerCaps (GDI32.@)
21979019 1704 */
a3960292 1705BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
fa68b75b 1706{
03468f7d
AJ
1707 lprs->nSize = sizeof(RASTERIZER_STATUS);
1708 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1709 lprs->nLanguageID = 0;
21979019 1710 return TRUE;
fa68b75b 1711}
bd34d4ff 1712
21979019 1713
21979019 1714/*************************************************************************
2aa85eed 1715 * GetKerningPairsA (GDI32.@)
21979019 1716 */
ecc6f063
SL
1717DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1718 LPKERNINGPAIR lpKerningPairs )
21979019 1719{
ecc6f063 1720 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
bd34d4ff 1721}
349a9531 1722
21979019
AJ
1723
1724/*************************************************************************
2aa85eed 1725 * GetKerningPairsW (GDI32.@)
21979019 1726 */
a3960292
AJ
1727DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1728 LPKERNINGPAIR lpKerningPairs )
21979019 1729{
ecc6f063
SL
1730 int i;
1731 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1732 for (i = 0; i < cPairs; i++)
1733 lpKerningPairs[i].iKernAmount = 0;
1734 return 0;
21979019 1735}
23946ad2 1736
642d3136 1737/*************************************************************************
2aa85eed 1738 * TranslateCharsetInfo [GDI32.@]
4f7d9ed1
DR
1739 *
1740 * Fills a CHARSETINFO structure for a character set, code page, or
1741 * font. This allows making the correspondance between different labelings
9a624916 1742 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
4f7d9ed1
DR
1743 * of the same encoding.
1744 *
1745 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1746 * only one codepage should be set in *lpSrc.
1747 *
1748 * RETURNS
1749 * TRUE on success, FALSE on failure.
1750 *
4f7d9ed1 1751 */
a3960292 1752BOOL WINAPI TranslateCharsetInfo(
2b3aa616 1753 LPDWORD lpSrc, /* [in]
4f7d9ed1
DR
1754 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1755 if flags == TCI_SRCCHARSET: a character set value
1756 if flags == TCI_SRCCODEPAGE: a code page value
1757 */
2b3aa616
PS
1758 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1759 DWORD flags /* [in] determines interpretation of lpSrc */
4f7d9ed1 1760) {
ab9e8bc9
DR
1761 int index = 0;
1762 switch (flags) {
1763 case TCI_SRCFONTSIG:
1764 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1765 break;
1766 case TCI_SRCCODEPAGE:
a3960292 1767 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
ab9e8bc9
DR
1768 break;
1769 case TCI_SRCCHARSET:
a3960292 1770 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
ab9e8bc9
DR
1771 break;
1772 default:
1773 return FALSE;
1774 }
1775 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1776 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
670cdc45
AJ
1777 return TRUE;
1778}
1779
e658d820 1780/*************************************************************************
2aa85eed 1781 * GetFontLanguageInfo (GDI32.@)
e658d820 1782 */
74bd0da3
SS
1783DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1784{
1785 FONTSIGNATURE fontsig;
1786 static const DWORD GCP_DBCS_MASK=0x003F0000,
1787 GCP_DIACRITIC_MASK=0x00000000,
1788 FLI_GLYPHS_MASK=0x00000000,
1789 GCP_GLYPHSHAPE_MASK=0x00000040,
1790 GCP_KASHIDA_MASK=0x00000000,
1791 GCP_LIGATE_MASK=0x00000000,
1792 GCP_USEKERNING_MASK=0x00000000,
1793 GCP_REORDER_MASK=0x00000060;
a3868218 1794
74bd0da3 1795 DWORD result=0;
a3868218 1796
74bd0da3
SS
1797 GetTextCharsetInfo( hdc, &fontsig, 0 );
1798 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1799
1800 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1801 result|=GCP_DBCS;
a3868218 1802
74bd0da3
SS
1803 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1804 result|=GCP_DIACRITIC;
a3868218 1805
74bd0da3
SS
1806 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1807 result|=FLI_GLYPHS;
a3868218 1808
74bd0da3
SS
1809 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1810 result|=GCP_GLYPHSHAPE;
a3868218 1811
74bd0da3
SS
1812 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1813 result|=GCP_KASHIDA;
a3868218 1814
74bd0da3
SS
1815 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1816 result|=GCP_LIGATE;
1817
1818 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1819 result|=GCP_USEKERNING;
a3868218 1820
74bd0da3
SS
1821 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1822 result|=GCP_REORDER;
a3868218 1823
74bd0da3 1824 return result;
e658d820
AJ
1825}
1826
642d3136 1827
767e6f6f 1828/*************************************************************************
2aa85eed 1829 * GetFontData [GDI32.@] Retrieve data for TrueType font
767e6f6f
AJ
1830 *
1831 * RETURNS
1832 *
9a624916 1833 * success: Number of bytes returned
767e6f6f
AJ
1834 * failure: GDI_ERROR
1835 *
1836 * NOTES
1837 *
9a624916 1838 * Calls SetLastError()
767e6f6f 1839 *
767e6f6f 1840 */
9a624916 1841DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
767e6f6f
AJ
1842 LPVOID buffer, DWORD length)
1843{
4e2024e8
HD
1844 DC *dc = DC_GetDCPtr(hdc);
1845 DWORD ret = GDI_ERROR;
1846
1847 if(!dc) return GDI_ERROR;
1848
1849 if(dc->gdiFont)
1850 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1851
1852 GDI_ReleaseObj(hdc);
1853 return ret;
767e6f6f 1854}
642d3136 1855
2903ca1b
DT
1856/*************************************************************************
1857 * GetGlyphIndicesA [GDI32.@]
1858 */
1859DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1860 LPWORD pgi, DWORD flags)
1861{
1862 DWORD ret;
1863 WCHAR *lpstrW;
1864 INT countW;
1865
547cdc2b
AJ
1866 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1867 hdc, debugstr_an(lpstr, count), count, pgi, flags);
2903ca1b
DT
1868
1869 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1870 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1871 HeapFree(GetProcessHeap(), 0, lpstrW);
1872
1873 return ret;
1874}
1875
1876/*************************************************************************
1877 * GetGlyphIndicesW [GDI32.@]
1878 */
1879DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1880 LPWORD pgi, DWORD flags)
1881{
1882 DC *dc = DC_GetDCPtr(hdc);
1883 DWORD ret = GDI_ERROR;
1884
547cdc2b
AJ
1885 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1886 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2903ca1b
DT
1887
1888 if(!dc) return GDI_ERROR;
1889
1890 if(dc->gdiFont)
1891 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1892
1893 GDI_ReleaseObj(hdc);
1894 return ret;
1895}
1896
642d3136 1897/*************************************************************************
2aa85eed 1898 * GetCharacterPlacementA [GDI32.@]
2259e44e
JS
1899 *
1900 * NOTES:
1901 * the web browser control of ie4 calls this with dwFlags=0
642d3136
AJ
1902 */
1903DWORD WINAPI
a3960292
AJ
1904GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1905 INT nMaxExtent, GCP_RESULTSA *lpResults,
642d3136
AJ
1906 DWORD dwFlags)
1907{
2903ca1b 1908 WCHAR *lpStringW;
8da26fb2 1909 INT uCountW, i;
2903ca1b
DT
1910 GCP_RESULTSW resultsW;
1911 DWORD ret;
1912 UINT font_cp;
2259e44e 1913
2903ca1b
DT
1914 TRACE("%s, %d, %d, 0x%08lx\n",
1915 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2259e44e 1916
2903ca1b
DT
1917 /* both structs are equal in size */
1918 memcpy(&resultsW, lpResults, sizeof(resultsW));
2259e44e 1919
2903ca1b 1920 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
8551a8f3
SS
1921 if(lpResults->lpOutString)
1922 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
2259e44e 1923
2903ca1b
DT
1924 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1925
8da26fb2
HD
1926 if(lpResults->lpOutString) {
1927 if(font_cp != CP_SYMBOL)
8551a8f3
SS
1928 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1929 lpResults->lpOutString, uCount, NULL, NULL );
1930 else
1931 for(i = 0; i < uCount; i++)
1932 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
8da26fb2 1933 }
2259e44e 1934
2903ca1b
DT
1935 HeapFree(GetProcessHeap(), 0, lpStringW);
1936 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2259e44e
JS
1937
1938 return ret;
642d3136
AJ
1939}
1940
1941/*************************************************************************
2aa85eed 1942 * GetCharacterPlacementW [GDI32.@]
74bd0da3
SS
1943 *
1944 * Retrieve information about a string. This includes the width, reordering,
1945 * Glyphing and so on.
1946 *
1947 * RETURNS
1948 *
c5f775a9 1949 * The width and height of the string if successful, 0 if failed.
74bd0da3
SS
1950 *
1951 * BUGS
1952 *
1953 * All flags except GCP_REORDER are not yet implemented.
1954 * Reordering is not 100% complient to the Windows BiDi method.
1955 * Caret positioning is not yet implemented.
1956 * Classes are not yet implemented.
1957 *
642d3136
AJ
1958 */
1959DWORD WINAPI
74bd0da3 1960GetCharacterPlacementW(
a3868218
PS
1961 HDC hdc, /* [in] Device context for which the rendering is to be done */
1962 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1963 INT uCount, /* [in] Number of WORDS in string. */
1964 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1965 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1966 DWORD dwFlags /* [in] Flags specifying how to process the string */
74bd0da3 1967 )
642d3136 1968{
bc939e56
GA
1969 DWORD ret=0;
1970 SIZE size;
2903ca1b 1971 UINT i, nSet;
bc939e56 1972
2903ca1b
DT
1973 TRACE("%s, %d, %d, 0x%08lx\n",
1974 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
bc939e56 1975
2903ca1b
DT
1976 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1977 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1978 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1979 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1980 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
bc939e56 1981
74bd0da3 1982 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
bc939e56
GA
1983 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1984 if(lpResults->lpClass) FIXME("classes not implemented\n");
bc939e56 1985
74bd0da3
SS
1986 nSet = (UINT)uCount;
1987 if(nSet > lpResults->nGlyphs)
1988 nSet = lpResults->nGlyphs;
2903ca1b 1989
74bd0da3
SS
1990 /* return number of initialized fields */
1991 lpResults->nGlyphs = nSet;
2903ca1b 1992
409374d9 1993 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
8551a8f3
SS
1994 {
1995 /* Treat the case where no special handling was requested in a fastpath way */
1996 /* copy will do if the GCP_REORDER flag is not set */
1997 if(lpResults->lpOutString)
409374d9 1998 strncpyW( lpResults->lpOutString, lpString, nSet );
8551a8f3
SS
1999
2000 if(lpResults->lpOrder)
2001 {
2002 for(i = 0; i < nSet; i++)
2003 lpResults->lpOrder[i] = i;
2004 }
409374d9 2005 } else
74bd0da3 2006 {
409374d9
SS
2007 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2008 nSet, lpResults->lpOrder );
74bd0da3 2009 }
bc939e56 2010
74bd0da3
SS
2011 /* FIXME: Will use the placement chars */
2012 if (lpResults->lpDx)
2013 {
2014 int c;
2015 for (i = 0; i < nSet; i++)
2016 {
2017 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2018 lpResults->lpDx[i]= c;
2019 }
2020 }
bc939e56 2021
2903ca1b
DT
2022 if(lpResults->lpGlyphs)
2023 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2024
bc939e56
GA
2025 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2026 ret = MAKELONG(size.cx, size.cy);
2027
2028 return ret;
642d3136 2029}
1beaae5f
PQ
2030
2031/*************************************************************************
2aa85eed 2032 * GetCharABCWidthsFloatA [GDI32.@]
1beaae5f 2033 */
a3960292 2034BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1beaae5f
PQ
2035 LPABCFLOAT lpABCF)
2036{
06c275a6 2037 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1beaae5f
PQ
2038 return 0;
2039}
2040
2041/*************************************************************************
2aa85eed 2042 * GetCharABCWidthsFloatW [GDI32.@]
1beaae5f 2043 */
a3960292
AJ
2044BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2045 UINT iLastChar, LPABCFLOAT lpABCF)
1beaae5f 2046{
06c275a6 2047 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1beaae5f
PQ
2048 return 0;
2049}
2050
2051/*************************************************************************
2aa85eed 2052 * GetCharWidthFloatA [GDI32.@]
1beaae5f 2053 */
a3960292
AJ
2054BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2055 UINT iLastChar, PFLOAT pxBuffer)
1beaae5f 2056{
06c275a6 2057 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1beaae5f
PQ
2058 return 0;
2059}
2060
2061/*************************************************************************
2aa85eed 2062 * GetCharWidthFloatW [GDI32.@]
1beaae5f 2063 */
a3960292
AJ
2064BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2065 UINT iLastChar, PFLOAT pxBuffer)
1beaae5f 2066{
06c275a6 2067 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1beaae5f
PQ
2068 return 0;
2069}
9a624916 2070
aafd54da
AJ
2071
2072/***********************************************************************
2073 * *
2074 * Font Resource API *
2075 * *
2076 ***********************************************************************/
aafd54da 2077
aafd54da 2078/***********************************************************************
2aa85eed 2079 * AddFontResourceA (GDI32.@)
aafd54da
AJ
2080 */
2081INT WINAPI AddFontResourceA( LPCSTR str )
2082{
8da26fb2 2083 return AddFontResourceExA( str, 0, NULL);
aafd54da
AJ
2084}
2085
aafd54da 2086/***********************************************************************
2aa85eed 2087 * AddFontResourceW (GDI32.@)
aafd54da
AJ
2088 */
2089INT WINAPI AddFontResourceW( LPCWSTR str )
2090{
8da26fb2
HD
2091 return AddFontResourceExW(str, 0, NULL);
2092}
2093
2094
2095/***********************************************************************
2096 * AddFontResourceExA (GDI32.@)
2097 */
2098INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2099{
2100 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2101 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2102 INT ret;
2103
2104 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2105 ret = AddFontResourceExW(strW, fl, pdv);
2106 HeapFree(GetProcessHeap(), 0, strW);
2107 return ret;
2108}
2109
2110/***********************************************************************
2111 * AddFontResourceExW (GDI32.@)
2112 */
2113INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2114{
2115 return WineEngAddFontResourceEx(str, fl, pdv);
aafd54da
AJ
2116}
2117
aafd54da 2118/***********************************************************************
2aa85eed 2119 * RemoveFontResourceA (GDI32.@)
aafd54da
AJ
2120 */
2121BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2122{
8da26fb2 2123 return RemoveFontResourceExA(str, 0, 0);
aafd54da
AJ
2124}
2125
aafd54da 2126/***********************************************************************
2aa85eed 2127 * RemoveFontResourceW (GDI32.@)
aafd54da
AJ
2128 */
2129BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2130{
8da26fb2
HD
2131 return RemoveFontResourceExW(str, 0, 0);
2132}
2133
2134/***********************************************************************
2135 * RemoveFontResourceExA (GDI32.@)
2136 */
2137BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2138{
2139 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2140 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2141 INT ret;
2142
2143 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2144 ret = RemoveFontResourceExW(strW, fl, pdv);
2145 HeapFree(GetProcessHeap(), 0, strW);
2146 return ret;
2147}
2148
2149/***********************************************************************
2150 * RemoveFontResourceExW (GDI32.@)
2151 */
2152BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2153{
2154 return WineEngRemoveFontResourceEx(str, fl, pdv);
aafd54da 2155}
c23f8578
HD
2156
2157/***********************************************************************
2158 * GetTextCharset (GDI32.@)
2159 */
2160UINT WINAPI GetTextCharset(HDC hdc)
2161{
2162 /* MSDN docs say this is equivalent */
2163 return GetTextCharsetInfo(hdc, NULL, 0);
2164}
2165
2166/***********************************************************************
2167 * GetTextCharsetInfo (GDI32.@)
2168 */
2169UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2170{
2171 UINT ret = DEFAULT_CHARSET;
2172 DC *dc = DC_GetDCPtr(hdc);
2173
2174 if (!dc) goto done;
2175
2176 if (dc->gdiFont)
2177 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2178
2179 GDI_ReleaseObj(hdc);
2180
2181done:
2182 if (ret == DEFAULT_CHARSET && fs)
2183 memset(fs, 0, sizeof(FONTSIGNATURE));
2184 return ret;
2185}