Properly check that the font resource is not already there.
[wine/multimedia.git] / objects / font.c
blob3fa2146b4863b9680b24ba320e76d9095007d4be
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
5 * 1997 Alex Korobka
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdlib.h>
23 #include <string.h>
24 #include <assert.h>
25 #include "winerror.h"
26 #include "winnls.h"
27 #include "wine/unicode.h"
28 #include "font.h"
29 #include "wine/debug.h"
30 #include "gdi.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(font);
33 WINE_DECLARE_DEBUG_CHANNEL(gdi);
35 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
36 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
37 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
38 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
39 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
41 static const struct gdi_obj_funcs font_funcs =
43 FONT_SelectObject, /* pSelectObject */
44 FONT_GetObject16, /* pGetObject16 */
45 FONT_GetObjectA, /* pGetObjectA */
46 FONT_GetObjectW, /* pGetObjectW */
47 NULL, /* pUnrealizeObject */
48 FONT_DeleteObject /* pDeleteObject */
51 #define ENUM_UNICODE 0x00000001
52 #define ENUM_CALLED 0x00000002
54 typedef struct
56 GDIOBJHDR header;
57 LOGFONTW logfont;
58 } FONTOBJ;
60 typedef struct
62 LPLOGFONT16 lpLogFontParam;
63 FONTENUMPROCEX16 lpEnumFunc;
64 LPARAM lpData;
66 LPNEWTEXTMETRICEX16 lpTextMetric;
67 LPENUMLOGFONTEX16 lpLogFont;
68 SEGPTR segTextMetric;
69 SEGPTR segLogFont;
70 HDC hdc;
71 DC *dc;
72 PHYSDEV physDev;
73 } fontEnum16;
75 typedef struct
77 LPLOGFONTW lpLogFontParam;
78 FONTENUMPROCEXW lpEnumFunc;
79 LPARAM lpData;
80 DWORD dwFlags;
81 HDC hdc;
82 DC *dc;
83 PHYSDEV physDev;
84 } fontEnum32;
87 * For TranslateCharsetInfo
89 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
90 #define MAXTCIINDEX 32
91 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
92 /* ANSI */
93 { ANSI_CHARSET, 1252, FS(0)},
94 { EASTEUROPE_CHARSET, 1250, FS(1)},
95 { RUSSIAN_CHARSET, 1251, FS(2)},
96 { GREEK_CHARSET, 1253, FS(3)},
97 { TURKISH_CHARSET, 1254, FS(4)},
98 { HEBREW_CHARSET, 1255, FS(5)},
99 { ARABIC_CHARSET, 1256, FS(6)},
100 { BALTIC_CHARSET, 1257, FS(7)},
101 { VIETNAMESE_CHARSET, 1258, FS(8)},
102 /* reserved by ANSI */
103 { DEFAULT_CHARSET, 0, FS(0)},
104 { DEFAULT_CHARSET, 0, FS(0)},
105 { DEFAULT_CHARSET, 0, FS(0)},
106 { DEFAULT_CHARSET, 0, FS(0)},
107 { DEFAULT_CHARSET, 0, FS(0)},
108 { DEFAULT_CHARSET, 0, FS(0)},
109 { DEFAULT_CHARSET, 0, FS(0)},
110 /* ANSI and OEM */
111 { THAI_CHARSET, 874, FS(16)},
112 { SHIFTJIS_CHARSET, 932, FS(17)},
113 { GB2312_CHARSET, 936, FS(18)},
114 { HANGEUL_CHARSET, 949, FS(19)},
115 { CHINESEBIG5_CHARSET, 950, FS(20)},
116 { JOHAB_CHARSET, 1361, FS(21)},
117 /* reserved for alternate ANSI and OEM */
118 { DEFAULT_CHARSET, 0, FS(0)},
119 { DEFAULT_CHARSET, 0, FS(0)},
120 { DEFAULT_CHARSET, 0, FS(0)},
121 { DEFAULT_CHARSET, 0, FS(0)},
122 { DEFAULT_CHARSET, 0, FS(0)},
123 { DEFAULT_CHARSET, 0, FS(0)},
124 { DEFAULT_CHARSET, 0, FS(0)},
125 { DEFAULT_CHARSET, 0, FS(0)},
126 /* reserved for system */
127 { DEFAULT_CHARSET, 0, FS(0)},
128 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
131 /* ### start build ### */
132 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROCEX16,LONG,LONG,WORD,LONG);
133 /* ### stop build ### */
135 /***********************************************************************
136 * LOGFONT conversion functions.
138 void FONT_LogFontATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
140 font16->lfHeight = font32->lfHeight;
141 font16->lfWidth = font32->lfWidth;
142 font16->lfEscapement = font32->lfEscapement;
143 font16->lfOrientation = font32->lfOrientation;
144 font16->lfWeight = font32->lfWeight;
145 font16->lfItalic = font32->lfItalic;
146 font16->lfUnderline = font32->lfUnderline;
147 font16->lfStrikeOut = font32->lfStrikeOut;
148 font16->lfCharSet = font32->lfCharSet;
149 font16->lfOutPrecision = font32->lfOutPrecision;
150 font16->lfClipPrecision = font32->lfClipPrecision;
151 font16->lfQuality = font32->lfQuality;
152 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
153 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
156 void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
158 font16->lfHeight = font32->lfHeight;
159 font16->lfWidth = font32->lfWidth;
160 font16->lfEscapement = font32->lfEscapement;
161 font16->lfOrientation = font32->lfOrientation;
162 font16->lfWeight = font32->lfWeight;
163 font16->lfItalic = font32->lfItalic;
164 font16->lfUnderline = font32->lfUnderline;
165 font16->lfStrikeOut = font32->lfStrikeOut;
166 font16->lfCharSet = font32->lfCharSet;
167 font16->lfOutPrecision = font32->lfOutPrecision;
168 font16->lfClipPrecision = font32->lfClipPrecision;
169 font16->lfQuality = font32->lfQuality;
170 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
171 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
172 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
173 font16->lfFaceName[LF_FACESIZE-1] = 0;
176 void FONT_LogFont16ToA( const LOGFONT16 *font16, LPLOGFONTA font32 )
178 font32->lfHeight = font16->lfHeight;
179 font32->lfWidth = font16->lfWidth;
180 font32->lfEscapement = font16->lfEscapement;
181 font32->lfOrientation = font16->lfOrientation;
182 font32->lfWeight = font16->lfWeight;
183 font32->lfItalic = font16->lfItalic;
184 font32->lfUnderline = font16->lfUnderline;
185 font32->lfStrikeOut = font16->lfStrikeOut;
186 font32->lfCharSet = font16->lfCharSet;
187 font32->lfOutPrecision = font16->lfOutPrecision;
188 font32->lfClipPrecision = font16->lfClipPrecision;
189 font32->lfQuality = font16->lfQuality;
190 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
191 lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
194 void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
196 font32->lfHeight = font16->lfHeight;
197 font32->lfWidth = font16->lfWidth;
198 font32->lfEscapement = font16->lfEscapement;
199 font32->lfOrientation = font16->lfOrientation;
200 font32->lfWeight = font16->lfWeight;
201 font32->lfItalic = font16->lfItalic;
202 font32->lfUnderline = font16->lfUnderline;
203 font32->lfStrikeOut = font16->lfStrikeOut;
204 font32->lfCharSet = font16->lfCharSet;
205 font32->lfOutPrecision = font16->lfOutPrecision;
206 font32->lfClipPrecision = font16->lfClipPrecision;
207 font32->lfQuality = font16->lfQuality;
208 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
209 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
210 font32->lfFaceName[LF_FACESIZE-1] = 0;
213 void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
215 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
216 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
217 LF_FACESIZE);
220 void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
222 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
223 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
224 LF_FACESIZE, NULL, NULL);
227 void FONT_EnumLogFontEx16ToA( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXA font32 )
229 FONT_LogFont16ToA( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
230 lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
231 lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
232 lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
235 void FONT_EnumLogFontEx16ToW( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXW font32 )
237 FONT_LogFont16ToW( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
239 MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
240 font32->elfFullName[LF_FULLFACESIZE-1] = 0;
241 MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
242 font32->elfStyle[LF_FACESIZE-1] = 0;
243 MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
244 font32->elfScript[LF_FACESIZE-1] = 0;
247 void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
249 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
251 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
252 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
253 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
254 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
255 font16->elfStyle, LF_FACESIZE, NULL, NULL );
256 font16->elfStyle[LF_FACESIZE-1] = '\0';
257 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
258 font16->elfScript, LF_FACESIZE, NULL, NULL );
259 font16->elfScript[LF_FACESIZE-1] = '\0';
262 void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
264 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
266 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
267 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
268 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
269 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
270 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
271 fontA->elfStyle[LF_FACESIZE-1] = '\0';
272 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
273 fontA->elfScript, LF_FACESIZE, NULL, NULL );
274 fontA->elfScript[LF_FACESIZE-1] = '\0';
277 /***********************************************************************
278 * TEXTMETRIC conversion functions.
280 void FONT_TextMetricATo16(const TEXTMETRICA *ptm32, LPTEXTMETRIC16 ptm16 )
282 ptm16->tmHeight = ptm32->tmHeight;
283 ptm16->tmAscent = ptm32->tmAscent;
284 ptm16->tmDescent = ptm32->tmDescent;
285 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
286 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
287 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
288 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
289 ptm16->tmWeight = ptm32->tmWeight;
290 ptm16->tmOverhang = ptm32->tmOverhang;
291 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
292 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
293 ptm16->tmFirstChar = ptm32->tmFirstChar;
294 ptm16->tmLastChar = ptm32->tmLastChar;
295 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
296 ptm16->tmBreakChar = ptm32->tmBreakChar;
297 ptm16->tmItalic = ptm32->tmItalic;
298 ptm16->tmUnderlined = ptm32->tmUnderlined;
299 ptm16->tmStruckOut = ptm32->tmStruckOut;
300 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
301 ptm16->tmCharSet = ptm32->tmCharSet;
304 void FONT_TextMetricWTo16(const TEXTMETRICW *ptm32, LPTEXTMETRIC16 ptm16 )
306 ptm16->tmHeight = ptm32->tmHeight;
307 ptm16->tmAscent = ptm32->tmAscent;
308 ptm16->tmDescent = ptm32->tmDescent;
309 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
310 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
311 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
312 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
313 ptm16->tmWeight = ptm32->tmWeight;
314 ptm16->tmOverhang = ptm32->tmOverhang;
315 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
316 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
317 ptm16->tmFirstChar = ptm32->tmFirstChar;
318 ptm16->tmLastChar = ptm32->tmLastChar;
319 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
320 ptm16->tmBreakChar = ptm32->tmBreakChar;
321 ptm16->tmItalic = ptm32->tmItalic;
322 ptm16->tmUnderlined = ptm32->tmUnderlined;
323 ptm16->tmStruckOut = ptm32->tmStruckOut;
324 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
325 ptm16->tmCharSet = ptm32->tmCharSet;
328 void FONT_TextMetric16ToA(const TEXTMETRIC16 *ptm16, LPTEXTMETRICA ptm32 )
330 ptm32->tmHeight = ptm16->tmHeight;
331 ptm32->tmAscent = ptm16->tmAscent;
332 ptm32->tmDescent = ptm16->tmDescent;
333 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
334 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
335 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
336 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
337 ptm32->tmWeight = ptm16->tmWeight;
338 ptm32->tmOverhang = ptm16->tmOverhang;
339 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
340 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
341 ptm32->tmFirstChar = ptm16->tmFirstChar;
342 ptm32->tmLastChar = ptm16->tmLastChar;
343 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
344 ptm32->tmBreakChar = ptm16->tmBreakChar;
345 ptm32->tmItalic = ptm16->tmItalic;
346 ptm32->tmUnderlined = ptm16->tmUnderlined;
347 ptm32->tmStruckOut = ptm16->tmStruckOut;
348 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
349 ptm32->tmCharSet = ptm16->tmCharSet;
352 void FONT_TextMetric16ToW(const TEXTMETRIC16 *ptm16, LPTEXTMETRICW ptm32 )
354 ptm32->tmHeight = ptm16->tmHeight;
355 ptm32->tmAscent = ptm16->tmAscent;
356 ptm32->tmDescent = ptm16->tmDescent;
357 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
358 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
359 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
360 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
361 ptm32->tmWeight = ptm16->tmWeight;
362 ptm32->tmOverhang = ptm16->tmOverhang;
363 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
364 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
365 ptm32->tmFirstChar = ptm16->tmFirstChar;
366 ptm32->tmLastChar = ptm16->tmLastChar;
367 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
368 ptm32->tmBreakChar = ptm16->tmBreakChar;
369 ptm32->tmItalic = ptm16->tmItalic;
370 ptm32->tmUnderlined = ptm16->tmUnderlined;
371 ptm32->tmStruckOut = ptm16->tmStruckOut;
372 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
373 ptm32->tmCharSet = ptm16->tmCharSet;
376 void FONT_TextMetricAToW(const TEXTMETRICA *ptm32A, LPTEXTMETRICW ptm32W )
378 ptm32W->tmHeight = ptm32A->tmHeight;
379 ptm32W->tmAscent = ptm32A->tmAscent;
380 ptm32W->tmDescent = ptm32A->tmDescent;
381 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
382 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
383 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
384 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
385 ptm32W->tmWeight = ptm32A->tmWeight;
386 ptm32W->tmOverhang = ptm32A->tmOverhang;
387 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
388 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
389 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
390 ptm32W->tmLastChar = ptm32A->tmLastChar;
391 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
392 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
393 ptm32W->tmItalic = ptm32A->tmItalic;
394 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
395 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
396 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
397 ptm32W->tmCharSet = ptm32A->tmCharSet;
400 void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
402 ptmA->tmHeight = ptmW->tmHeight;
403 ptmA->tmAscent = ptmW->tmAscent;
404 ptmA->tmDescent = ptmW->tmDescent;
405 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
406 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
407 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
408 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
409 ptmA->tmWeight = ptmW->tmWeight;
410 ptmA->tmOverhang = ptmW->tmOverhang;
411 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
412 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
413 ptmA->tmFirstChar = ptmW->tmFirstChar;
414 ptmA->tmLastChar = ptmW->tmLastChar;
415 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
416 ptmA->tmBreakChar = ptmW->tmBreakChar;
417 ptmA->tmItalic = ptmW->tmItalic;
418 ptmA->tmUnderlined = ptmW->tmUnderlined;
419 ptmA->tmStruckOut = ptmW->tmStruckOut;
420 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
421 ptmA->tmCharSet = ptmW->tmCharSet;
425 void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
427 FONT_TextMetricWTo16((LPTEXTMETRICW)ptmW, (LPTEXTMETRIC16)ptm16);
428 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
429 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
430 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
431 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
432 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
435 void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
437 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
438 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
439 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
440 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
441 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
442 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
445 void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16 *ptm16, LPNEWTEXTMETRICEXW ptmW )
447 FONT_TextMetric16ToW((LPTEXTMETRIC16)ptm16, (LPTEXTMETRICW)ptmW);
448 ptmW->ntmTm.ntmFlags = ptm16->ntmTm.ntmFlags;
449 ptmW->ntmTm.ntmSizeEM = ptm16->ntmTm.ntmSizeEM;
450 ptmW->ntmTm.ntmCellHeight = ptm16->ntmTm.ntmCellHeight;
451 ptmW->ntmTm.ntmAvgWidth = ptm16->ntmTm.ntmAvgWidth;
452 memcpy(&ptmW->ntmFontSig, &ptm16->ntmFontSig, sizeof(FONTSIGNATURE));
456 /***********************************************************************
457 * CreateFontIndirect (GDI.57)
459 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
461 LOGFONTW lfW;
463 if(plf16) {
464 FONT_LogFont16ToW( plf16, &lfW );
465 return CreateFontIndirectW( &lfW );
466 } else {
467 return CreateFontIndirectW( NULL );
472 /***********************************************************************
473 * CreateFontIndirectA (GDI32.@)
475 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
477 LOGFONTW lfW;
479 if (plfA) {
480 FONT_LogFontAToW( plfA, &lfW );
481 return CreateFontIndirectW( &lfW );
482 } else
483 return CreateFontIndirectW( NULL );
487 /***********************************************************************
488 * CreateFontIndirectW (GDI32.@)
490 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
492 HFONT hFont = 0;
494 if (plf)
496 FONTOBJ* fontPtr;
497 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont, &font_funcs )))
499 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
501 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
502 plf->lfHeight, plf->lfWidth,
503 plf->lfEscapement, plf->lfOrientation,
504 plf->lfPitchAndFamily,
505 debugstr_w(plf->lfFaceName),
506 plf->lfWeight > 400 ? "Bold" : "",
507 plf->lfItalic ? "Italic" : "", hFont);
509 if (plf->lfEscapement != plf->lfOrientation) {
510 /* this should really depend on whether GM_ADVANCED is set */
511 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
512 WARN("orientation angle %f set to "
513 "escapement angle %f for new font %04x\n",
514 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
516 GDI_ReleaseObj( hFont );
519 else WARN("(NULL) => NULL\n");
521 return hFont;
524 /***********************************************************************
525 * CreateFont (GDI.56)
527 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
528 INT16 weight, BYTE italic, BYTE underline,
529 BYTE strikeout, BYTE charset, BYTE outpres,
530 BYTE clippres, BYTE quality, BYTE pitch,
531 LPCSTR name )
533 LOGFONT16 logfont;
535 logfont.lfHeight = height;
536 logfont.lfWidth = width;
537 logfont.lfEscapement = esc;
538 logfont.lfOrientation = orient;
539 logfont.lfWeight = weight;
540 logfont.lfItalic = italic;
541 logfont.lfUnderline = underline;
542 logfont.lfStrikeOut = strikeout;
543 logfont.lfCharSet = charset;
544 logfont.lfOutPrecision = outpres;
545 logfont.lfClipPrecision = clippres;
546 logfont.lfQuality = quality;
547 logfont.lfPitchAndFamily = pitch;
549 if (name)
550 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
551 else
552 logfont.lfFaceName[0] = '\0';
554 return CreateFontIndirect16( &logfont );
557 /*************************************************************************
558 * CreateFontA (GDI32.@)
560 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
561 INT orient, INT weight, DWORD italic,
562 DWORD underline, DWORD strikeout, DWORD charset,
563 DWORD outpres, DWORD clippres, DWORD quality,
564 DWORD pitch, LPCSTR name )
566 LOGFONTA logfont;
568 logfont.lfHeight = height;
569 logfont.lfWidth = width;
570 logfont.lfEscapement = esc;
571 logfont.lfOrientation = orient;
572 logfont.lfWeight = weight;
573 logfont.lfItalic = italic;
574 logfont.lfUnderline = underline;
575 logfont.lfStrikeOut = strikeout;
576 logfont.lfCharSet = charset;
577 logfont.lfOutPrecision = outpres;
578 logfont.lfClipPrecision = clippres;
579 logfont.lfQuality = quality;
580 logfont.lfPitchAndFamily = pitch;
582 if (name)
583 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
584 else
585 logfont.lfFaceName[0] = '\0';
587 return CreateFontIndirectA( &logfont );
590 /*************************************************************************
591 * CreateFontW (GDI32.@)
593 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
594 INT orient, INT weight, DWORD italic,
595 DWORD underline, DWORD strikeout, DWORD charset,
596 DWORD outpres, DWORD clippres, DWORD quality,
597 DWORD pitch, LPCWSTR name )
599 LOGFONTW logfont;
601 logfont.lfHeight = height;
602 logfont.lfWidth = width;
603 logfont.lfEscapement = esc;
604 logfont.lfOrientation = orient;
605 logfont.lfWeight = weight;
606 logfont.lfItalic = italic;
607 logfont.lfUnderline = underline;
608 logfont.lfStrikeOut = strikeout;
609 logfont.lfCharSet = charset;
610 logfont.lfOutPrecision = outpres;
611 logfont.lfClipPrecision = clippres;
612 logfont.lfQuality = quality;
613 logfont.lfPitchAndFamily = pitch;
615 if (name)
616 lstrcpynW(logfont.lfFaceName, name,
617 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
618 else
619 logfont.lfFaceName[0] = '\0';
621 return CreateFontIndirectW( &logfont );
625 /***********************************************************************
626 * FONT_SelectObject
628 * If the driver supports vector fonts we create a gdi font first and
629 * then call the driver to give it a chance to supply its own device
630 * font. If the driver wants to do this it returns TRUE and we can
631 * delete the gdi font, if the driver wants to use the gdi font it
632 * should return FALSE, to signal an error return GDI_ERROR. For
633 * drivers that don't support vector fonts they must supply their own
634 * font.
636 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
638 HGDIOBJ ret = 0;
639 DC *dc = DC_GetDCPtr( hdc );
641 if (!dc) return 0;
643 if (dc->hFont != handle || dc->gdiFont == NULL)
645 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
646 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
649 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
651 if (ret && dc->gdiFont) dc->gdiFont = 0;
653 if (ret == GDI_ERROR)
654 ret = 0; /* SelectObject returns 0 on error */
655 else
657 ret = dc->hFont;
658 dc->hFont = handle;
660 GDI_ReleaseObj( hdc );
661 return ret;
665 /***********************************************************************
666 * FONT_GetObject16
668 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
670 FONTOBJ *font = obj;
671 LOGFONT16 lf16;
673 FONT_LogFontWTo16( &font->logfont, &lf16 );
675 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
676 memcpy( buffer, &lf16, count );
677 return count;
680 /***********************************************************************
681 * FONT_GetObjectA
683 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
685 FONTOBJ *font = obj;
686 LOGFONTA lfA;
688 FONT_LogFontWToA( &font->logfont, &lfA );
690 if (count > sizeof(lfA)) count = sizeof(lfA);
691 memcpy( buffer, &lfA, count );
692 return count;
695 /***********************************************************************
696 * FONT_GetObjectW
698 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
700 FONTOBJ *font = obj;
701 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
702 memcpy( buffer, &font->logfont, count );
703 return count;
707 /***********************************************************************
708 * FONT_DeleteObject
710 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
712 WineEngDestroyFontInstance( handle );
713 return GDI_FreeObject( handle, obj );
717 /***********************************************************************
718 * FONT_EnumInstance16
720 * Called by the device driver layer to pass font info
721 * down to the application.
723 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
724 DWORD fType, LPARAM lp )
726 fontEnum16 *pfe = (fontEnum16*)lp;
727 INT ret = 1;
728 DC *dc;
730 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
731 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
733 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
734 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
735 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
737 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
738 (UINT16)fType, (LPARAM)pfe->lpData );
739 /* get the lock again and make sure the DC is still valid */
740 dc = DC_GetDCPtr( pfe->hdc );
741 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
743 if (dc) GDI_ReleaseObj( pfe->hdc );
744 pfe->hdc = 0; /* make sure we don't try to release it later on */
745 ret = 0;
748 return ret;
751 /***********************************************************************
752 * FONT_EnumInstance
754 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
755 DWORD fType, LPARAM lp )
757 fontEnum32 *pfe = (fontEnum32*)lp;
758 INT ret = 1;
759 DC *dc;
761 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
762 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
763 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
765 /* convert font metrics */
766 ENUMLOGFONTEXA logfont;
767 NEWTEXTMETRICEXA tmA;
769 pfe->dwFlags |= ENUM_CALLED;
770 if (!(pfe->dwFlags & ENUM_UNICODE))
772 FONT_EnumLogFontExWToA( plf, &logfont);
773 FONT_NewTextMetricExWToA( ptm, &tmA );
774 plf = (LPENUMLOGFONTEXW)&logfont;
775 ptm = (LPNEWTEXTMETRICEXW)&tmA;
777 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
779 ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
781 /* get the lock again and make sure the DC is still valid */
782 dc = DC_GetDCPtr( pfe->hdc );
783 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
785 if (dc) GDI_ReleaseObj( pfe->hdc );
786 pfe->hdc = 0; /* make sure we don't try to release it later on */
787 ret = 0;
790 return ret;
793 /***********************************************************************
794 * EnumFontFamiliesEx (GDI.613)
796 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
797 FONTENUMPROCEX16 efproc, LPARAM lParam,
798 DWORD dwFlags)
800 fontEnum16 fe16;
801 INT16 retVal = 0;
802 DC* dc = DC_GetDCPtr( hDC );
804 if (!dc) return 0;
805 fe16.hdc = hDC;
806 fe16.dc = dc;
807 fe16.physDev = dc->physDev;
809 if (dc->funcs->pEnumDeviceFonts)
811 NEWTEXTMETRICEX16 tm16;
812 ENUMLOGFONTEX16 lf16;
813 LOGFONTW lfW;
814 FONT_LogFont16ToW(plf, &lfW);
816 fe16.lpLogFontParam = plf;
817 fe16.lpEnumFunc = efproc;
818 fe16.lpData = lParam;
819 fe16.lpTextMetric = &tm16;
820 fe16.lpLogFont = &lf16;
821 fe16.segTextMetric = MapLS( &tm16 );
822 fe16.segLogFont = MapLS( &lf16 );
824 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
825 FONT_EnumInstance16, (LPARAM)&fe16 );
826 UnMapLS( fe16.segTextMetric );
827 UnMapLS( fe16.segLogFont );
829 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
830 return retVal;
833 /***********************************************************************
834 * FONT_EnumFontFamiliesEx
836 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
837 FONTENUMPROCEXW efproc,
838 LPARAM lParam, DWORD dwUnicode)
840 INT ret = 1, ret2;
841 DC *dc = DC_GetDCPtr( hDC );
842 fontEnum32 fe32;
843 BOOL enum_gdi_fonts;
845 if (!dc) return 0;
847 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
848 plf->lfCharSet);
849 fe32.lpLogFontParam = plf;
850 fe32.lpEnumFunc = efproc;
851 fe32.lpData = lParam;
852 fe32.dwFlags = dwUnicode;
853 fe32.hdc = hDC;
854 fe32.dc = dc;
855 fe32.physDev = dc->physDev;
857 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
859 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
861 ret = 0;
862 goto done;
865 if (enum_gdi_fonts)
866 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
867 fe32.dwFlags &= ~ENUM_CALLED;
868 if (ret && dc->funcs->pEnumDeviceFonts) {
869 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
870 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
871 ret = ret2;
873 done:
874 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
875 return ret;
878 /***********************************************************************
879 * EnumFontFamiliesExW (GDI32.@)
881 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
882 FONTENUMPROCEXW efproc,
883 LPARAM lParam, DWORD dwFlags )
885 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
888 /***********************************************************************
889 * EnumFontFamiliesExA (GDI32.@)
891 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
892 FONTENUMPROCEXA efproc,
893 LPARAM lParam, DWORD dwFlags)
895 LOGFONTW lfW;
896 FONT_LogFontAToW( plf, &lfW );
898 return FONT_EnumFontFamiliesEx( hDC, &lfW,
899 (FONTENUMPROCEXW)efproc, lParam, 0);
902 /***********************************************************************
903 * EnumFontFamilies (GDI.330)
905 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
906 FONTENUMPROC16 efproc, LPARAM lpData )
908 LOGFONT16 lf;
910 lf.lfCharSet = DEFAULT_CHARSET;
911 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
912 else lf.lfFaceName[0] = '\0';
914 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
917 /***********************************************************************
918 * EnumFontFamiliesA (GDI32.@)
920 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
921 FONTENUMPROCA efproc, LPARAM lpData )
923 LOGFONTA lf;
925 lf.lfCharSet = DEFAULT_CHARSET;
926 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
927 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
929 return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
932 /***********************************************************************
933 * EnumFontFamiliesW (GDI32.@)
935 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
936 FONTENUMPROCW efproc, LPARAM lpData )
938 LOGFONTW lf;
940 lf.lfCharSet = DEFAULT_CHARSET;
941 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
942 else lf.lfFaceName[0] = 0;
944 return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
947 /***********************************************************************
948 * EnumFonts (GDI.70)
950 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
951 LPARAM lpData )
953 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
956 /***********************************************************************
957 * EnumFontsA (GDI32.@)
959 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
960 LPARAM lpData )
962 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
965 /***********************************************************************
966 * EnumFontsW (GDI32.@)
968 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
969 LPARAM lpData )
971 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
975 /***********************************************************************
976 * GetTextCharacterExtra (GDI.89)
978 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
980 return (INT16)GetTextCharacterExtra( hdc );
984 /***********************************************************************
985 * GetTextCharacterExtra (GDI32.@)
987 INT WINAPI GetTextCharacterExtra( HDC hdc )
989 INT ret;
990 DC *dc = DC_GetDCPtr( hdc );
991 if (!dc) return 0;
992 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
993 / dc->vportExtX );
994 GDI_ReleaseObj( hdc );
995 return ret;
999 /***********************************************************************
1000 * SetTextCharacterExtra (GDI.8)
1002 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
1004 return (INT16)SetTextCharacterExtra( hdc, extra );
1008 /***********************************************************************
1009 * SetTextCharacterExtra (GDI32.@)
1011 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
1013 INT prev;
1014 DC * dc = DC_GetDCPtr( hdc );
1015 if (!dc) return 0;
1016 if (dc->funcs->pSetTextCharacterExtra)
1017 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
1018 else
1020 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
1021 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
1022 dc->charExtra = abs(extra);
1024 GDI_ReleaseObj( hdc );
1025 return prev;
1029 /***********************************************************************
1030 * SetTextJustification (GDI.10)
1032 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
1034 return SetTextJustification( hdc, extra, breaks );
1038 /***********************************************************************
1039 * SetTextJustification (GDI32.@)
1041 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
1043 BOOL ret = TRUE;
1044 DC * dc = DC_GetDCPtr( hdc );
1045 if (!dc) return FALSE;
1046 if (dc->funcs->pSetTextJustification)
1047 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
1048 else
1050 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
1051 if (!extra) breaks = 0;
1052 dc->breakTotalExtra = extra;
1053 dc->breakCount = breaks;
1054 if (breaks)
1056 dc->breakExtra = extra / breaks;
1057 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
1059 else
1061 dc->breakExtra = 0;
1062 dc->breakRem = 0;
1065 GDI_ReleaseObj( hdc );
1066 return ret;
1070 /***********************************************************************
1071 * GetTextFace (GDI.92)
1073 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
1075 return GetTextFaceA(hdc,count,name);
1078 /***********************************************************************
1079 * GetTextFaceA (GDI32.@)
1081 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
1083 INT res = GetTextFaceW(hdc, 0, NULL);
1084 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
1085 GetTextFaceW( hdc, res, nameW );
1087 if (name)
1088 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
1089 NULL, NULL);
1090 else
1091 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
1092 HeapFree( GetProcessHeap(), 0, nameW );
1093 return res;
1096 /***********************************************************************
1097 * GetTextFaceW (GDI32.@)
1099 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
1101 FONTOBJ *font;
1102 INT ret = 0;
1104 DC * dc = DC_GetDCPtr( hdc );
1105 if (!dc) return 0;
1107 if(dc->gdiFont)
1108 ret = WineEngGetTextFace(dc->gdiFont, count, name);
1109 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
1111 if (name)
1113 lstrcpynW( name, font->logfont.lfFaceName, count );
1114 ret = strlenW(name);
1116 else ret = strlenW(font->logfont.lfFaceName) + 1;
1117 GDI_ReleaseObj( dc->hFont );
1119 GDI_ReleaseObj( hdc );
1120 return ret;
1124 /***********************************************************************
1125 * GetTextExtent (GDI.91)
1127 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1129 SIZE16 size;
1130 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1131 return MAKELONG( size.cx, size.cy );
1135 /***********************************************************************
1136 * GetTextExtentPoint (GDI.471)
1138 * FIXME: Should this have a bug for compatibility?
1139 * Original Windows versions of GetTextExtentPoint{A,W} have documented
1140 * bugs (-> MSDN KB q147647.txt).
1142 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1143 LPSIZE16 size )
1145 SIZE size32;
1146 BOOL ret;
1147 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1148 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1149 size->cx = size32.cx;
1150 size->cy = size32.cy;
1151 return (BOOL16)ret;
1155 /***********************************************************************
1156 * GetTextExtentPoint32A (GDI32.@)
1158 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1159 LPSIZE size )
1161 BOOL ret = FALSE;
1162 INT wlen;
1163 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1165 if (p) {
1166 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1167 HeapFree( GetProcessHeap(), 0, p );
1170 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1171 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1172 return ret;
1176 /***********************************************************************
1177 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
1179 * Computes width and height of the specified string.
1181 * RETURNS
1182 * Success: TRUE
1183 * Failure: FALSE
1185 BOOL WINAPI GetTextExtentPoint32W(
1186 HDC hdc, /* [in] Handle of device context */
1187 LPCWSTR str, /* [in] Address of text string */
1188 INT count, /* [in] Number of characters in string */
1189 LPSIZE size) /* [out] Address of structure for string size */
1191 BOOL ret = FALSE;
1192 DC * dc = DC_GetDCPtr( hdc );
1193 if (!dc) return FALSE;
1195 if(dc->gdiFont) {
1196 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1197 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1198 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1200 else if(dc->funcs->pGetTextExtentPoint)
1201 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
1203 GDI_ReleaseObj( hdc );
1205 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1206 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1207 return ret;
1210 /***********************************************************************
1211 * GetTextExtentPointI [GDI32.@]
1213 * Computes width and height of the array of glyph indices.
1215 * RETURNS
1216 * Success: TRUE
1217 * Failure: FALSE
1219 BOOL WINAPI GetTextExtentPointI(
1220 HDC hdc, /* [in] Handle of device context */
1221 const WORD *indices, /* [in] Address of glyph index array */
1222 INT count, /* [in] Number of glyphs in array */
1223 LPSIZE size) /* [out] Address of structure for string size */
1225 BOOL ret = FALSE;
1226 DC * dc = DC_GetDCPtr( hdc );
1227 if (!dc) return FALSE;
1229 if(dc->gdiFont) {
1230 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1231 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1232 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1234 else if(dc->funcs->pGetTextExtentPoint) {
1235 FIXME("calling GetTextExtentPoint\n");
1236 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1239 GDI_ReleaseObj( hdc );
1241 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
1242 hdc, indices, count, size, size->cx, size->cy );
1243 return ret;
1247 /***********************************************************************
1248 * GetTextExtentPointA (GDI32.@)
1250 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1251 LPSIZE size )
1253 TRACE("not bug compatible.\n");
1254 return GetTextExtentPoint32A( hdc, str, count, size );
1257 /***********************************************************************
1258 * GetTextExtentPointW (GDI32.@)
1260 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1261 LPSIZE size )
1263 TRACE("not bug compatible.\n");
1264 return GetTextExtentPoint32W( hdc, str, count, size );
1268 /***********************************************************************
1269 * GetTextExtentExPointA (GDI32.@)
1271 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1272 INT maxExt, LPINT lpnFit,
1273 LPINT alpDx, LPSIZE size )
1275 BOOL ret;
1276 INT wlen;
1277 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1278 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1279 HeapFree( GetProcessHeap(), 0, p );
1280 return ret;
1284 /***********************************************************************
1285 * GetTextExtentExPointW (GDI32.@)
1287 * Return the size of the string as it would be if it was output properly by
1288 * e.g. TextOut.
1290 * This should include
1291 * - Intercharacter spacing
1292 * - justification spacing (not yet done)
1293 * - kerning? see below
1295 * Kerning. Since kerning would be carried out by the rendering code it should
1296 * be done by the driver. However they don't support it yet. Also I am not
1297 * yet persuaded that (certainly under Win95) any kerning is actually done.
1299 * str: According to MSDN this should be null-terminated. That is not true; a
1300 * null will not terminate it early.
1301 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1302 * than count. I have seen it be either the size of the full string or
1303 * 1 less than the size of the full string. I have not seen it bear any
1304 * resemblance to the portion that would fit.
1305 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1306 * trailing intercharacter spacing and any trailing justification.
1308 * FIXME
1309 * Currently we do this by measuring each character etc. We should do it by
1310 * passing the request to the driver, perhaps by extending the
1311 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1312 * thinking about kerning issues and rounding issues in the justification.
1315 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1316 INT maxExt, LPINT lpnFit,
1317 LPINT alpDx, LPSIZE size )
1319 int index, nFit, extent;
1320 SIZE tSize;
1321 BOOL ret = FALSE;
1323 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1325 size->cx = size->cy = nFit = extent = 0;
1326 for(index = 0; index < count; index++)
1328 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1329 /* GetTextExtentPoint includes intercharacter spacing. */
1330 /* FIXME - justification needs doing yet. Remember that the base
1331 * data will not be in logical coordinates.
1333 extent += tSize.cx;
1334 if( !lpnFit || extent <= maxExt )
1335 /* It is allowed to be equal. */
1337 nFit++;
1338 if( alpDx ) alpDx[index] = extent;
1340 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1341 str++;
1343 size->cx = extent;
1344 if(lpnFit) *lpnFit = nFit;
1345 ret = TRUE;
1347 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1349 done:
1350 return ret;
1353 /***********************************************************************
1354 * GetTextMetrics (GDI.93)
1356 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1358 TEXTMETRICW tm32;
1360 if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1361 FONT_TextMetricWTo16( &tm32, metrics );
1362 return TRUE;
1366 /***********************************************************************
1367 * GetTextMetricsA (GDI32.@)
1369 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1371 TEXTMETRICW tm32;
1373 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1374 FONT_TextMetricWToA( &tm32, metrics );
1375 return TRUE;
1378 /***********************************************************************
1379 * GetTextMetricsW (GDI32.@)
1381 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1383 BOOL ret = FALSE;
1384 DC * dc = DC_GetDCPtr( hdc );
1385 if (!dc) return FALSE;
1387 if (dc->gdiFont)
1388 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1389 else if (dc->funcs->pGetTextMetrics)
1390 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1392 if (ret)
1394 /* device layer returns values in device units
1395 * therefore we have to convert them to logical */
1397 #define WDPTOLP(x) ((x<0)? \
1398 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1399 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1400 #define HDPTOLP(y) ((y<0)? \
1401 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1402 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1404 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1405 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1406 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1407 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1408 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1409 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1410 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1411 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1412 ret = TRUE;
1414 TRACE("text metrics:\n"
1415 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1416 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1417 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1418 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1419 " PitchAndFamily = %02x\n"
1420 " --------------------\n"
1421 " InternalLeading = %li\n"
1422 " Ascent = %li\n"
1423 " Descent = %li\n"
1424 " Height = %li\n",
1425 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1426 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1427 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1428 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1429 metrics->tmPitchAndFamily,
1430 metrics->tmInternalLeading,
1431 metrics->tmAscent,
1432 metrics->tmDescent,
1433 metrics->tmHeight );
1435 GDI_ReleaseObj( hdc );
1436 return ret;
1440 /***********************************************************************
1441 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1443 * NOTES
1444 * lpOTM should be LPOUTLINETEXTMETRIC
1446 * RETURNS
1447 * Success: Non-zero or size of required buffer
1448 * Failure: 0
1450 UINT16 WINAPI GetOutlineTextMetrics16(
1451 HDC16 hdc, /* [in] Handle of device context */
1452 UINT16 cbData, /* [in] Size of metric data array */
1453 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1455 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1456 return 0;
1460 /***********************************************************************
1461 * GetOutlineTextMetricsA (GDI32.@)
1462 * Gets metrics for TrueType fonts.
1465 * RETURNS
1466 * Success: Non-zero or size of required buffer
1467 * Failure: 0
1469 UINT WINAPI GetOutlineTextMetricsA(
1470 HDC hdc, /* [in] Handle of device context */
1471 UINT cbData, /* [in] Size of metric data array */
1472 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1474 char buf[512], *ptr;
1475 UINT ret, needed;
1476 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1477 INT left, len;
1479 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1480 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1481 return 0;
1482 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1483 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1486 needed = sizeof(OUTLINETEXTMETRICA);
1487 if(lpOTMW->otmpFamilyName)
1488 needed += WideCharToMultiByte(CP_ACP, 0,
1489 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1490 NULL, 0, NULL, NULL);
1491 if(lpOTMW->otmpFaceName)
1492 needed += WideCharToMultiByte(CP_ACP, 0,
1493 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1494 NULL, 0, NULL, NULL);
1495 if(lpOTMW->otmpStyleName)
1496 needed += WideCharToMultiByte(CP_ACP, 0,
1497 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1498 NULL, 0, NULL, NULL);
1499 if(lpOTMW->otmpFullName)
1500 needed += WideCharToMultiByte(CP_ACP, 0,
1501 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1502 NULL, 0, NULL, NULL);
1504 if(!lpOTM) {
1505 ret = needed;
1506 goto end;
1509 if(needed > cbData) {
1510 ret = 0;
1511 goto end;
1515 lpOTM->otmSize = needed;
1516 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1517 lpOTM->otmFiller = 0;
1518 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1519 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1520 lpOTM->otmfsType = lpOTMW->otmfsType;
1521 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1522 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1523 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1524 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1525 lpOTM->otmAscent = lpOTMW->otmAscent;
1526 lpOTM->otmDescent = lpOTMW->otmDescent;
1527 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1528 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1529 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1530 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1531 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1532 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1533 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1534 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1535 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1536 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1537 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1538 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1539 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1540 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1541 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1542 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1545 ptr = (char*)(lpOTM + 1);
1546 left = needed - sizeof(*lpOTM);
1548 if(lpOTMW->otmpFamilyName) {
1549 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1550 len = WideCharToMultiByte(CP_ACP, 0,
1551 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1552 ptr, left, NULL, NULL);
1553 left -= len;
1554 ptr += len;
1555 } else
1556 lpOTM->otmpFamilyName = 0;
1558 if(lpOTMW->otmpFaceName) {
1559 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1560 len = WideCharToMultiByte(CP_ACP, 0,
1561 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1562 ptr, left, NULL, NULL);
1563 left -= len;
1564 ptr += len;
1565 } else
1566 lpOTM->otmpFaceName = 0;
1568 if(lpOTMW->otmpStyleName) {
1569 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1570 len = WideCharToMultiByte(CP_ACP, 0,
1571 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1572 ptr, left, NULL, NULL);
1573 left -= len;
1574 ptr += len;
1575 } else
1576 lpOTM->otmpStyleName = 0;
1578 if(lpOTMW->otmpFullName) {
1579 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1580 len = WideCharToMultiByte(CP_ACP, 0,
1581 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1582 ptr, left, NULL, NULL);
1583 left -= len;
1584 } else
1585 lpOTM->otmpFullName = 0;
1587 assert(left == 0);
1589 ret = needed;
1591 end:
1592 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1593 HeapFree(GetProcessHeap(), 0, lpOTMW);
1595 return ret;
1599 /***********************************************************************
1600 * GetOutlineTextMetricsW [GDI32.@]
1602 UINT WINAPI GetOutlineTextMetricsW(
1603 HDC hdc, /* [in] Handle of device context */
1604 UINT cbData, /* [in] Size of metric data array */
1605 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1607 DC *dc = DC_GetDCPtr( hdc );
1608 UINT ret;
1610 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1611 if(!dc) return 0;
1613 if(dc->gdiFont)
1614 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1616 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1617 but really this should just be a return 0. */
1619 ret = sizeof(*lpOTM);
1620 if (lpOTM) {
1621 if(cbData < ret)
1622 ret = 0;
1623 else {
1624 memset(lpOTM, 0, ret);
1625 lpOTM->otmSize = sizeof(*lpOTM);
1626 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1628 Further fill of the structure not implemented,
1629 Needs real values for the structure members
1634 GDI_ReleaseObj(hdc);
1635 return ret;
1639 /***********************************************************************
1640 * GetCharWidth (GDI.350)
1642 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1643 LPINT16 buffer )
1645 BOOL retVal = FALSE;
1647 if( firstChar != lastChar )
1649 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1650 sizeof(INT)*(1 + (lastChar - firstChar)));
1651 if( buf32 )
1653 LPINT obuf32 = buf32;
1654 int i;
1656 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1657 if (retVal)
1659 for (i = firstChar; i <= lastChar; i++)
1660 *buffer++ = *buf32++;
1662 HeapFree(GetProcessHeap(), 0, obuf32);
1665 else /* happens quite often to warrant a special treatment */
1667 INT chWidth;
1668 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1669 *buffer = chWidth;
1671 return retVal;
1675 /***********************************************************************
1676 * GetCharWidthW (GDI32.@)
1677 * GetCharWidth32W (GDI32.@)
1679 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1680 LPINT buffer )
1682 UINT i, extra;
1683 BOOL ret = FALSE;
1684 DC * dc = DC_GetDCPtr( hdc );
1685 if (!dc) return FALSE;
1687 if (dc->gdiFont)
1688 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1689 else if (dc->funcs->pGetCharWidth)
1690 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1692 if (ret)
1694 /* convert device units to logical */
1696 extra = dc->vportExtX >> 1;
1697 for( i = firstChar; i <= lastChar; i++, buffer++ )
1698 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1699 ret = TRUE;
1701 GDI_ReleaseObj( hdc );
1702 return ret;
1706 /***********************************************************************
1707 * GetCharWidthA (GDI32.@)
1708 * GetCharWidth32A (GDI32.@)
1710 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1711 LPINT buffer )
1713 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1714 LPSTR str;
1715 LPWSTR wstr;
1716 BOOL ret = TRUE;
1718 if(count <= 0) return FALSE;
1720 str = HeapAlloc(GetProcessHeap(), 0, count);
1721 for(i = 0; i < count; i++)
1722 str[i] = (BYTE)(firstChar + i);
1724 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1726 for(i = 0; i < wlen; i++)
1728 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1730 ret = FALSE;
1731 break;
1733 buffer++;
1736 HeapFree(GetProcessHeap(), 0, str);
1737 HeapFree(GetProcessHeap(), 0, wstr);
1739 return ret;
1743 /* FIXME: all following APIs ******************************************/
1746 /***********************************************************************
1747 * SetMapperFlags (GDI.349)
1749 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1751 return SetMapperFlags( hDC, dwFlag );
1755 /***********************************************************************
1756 * SetMapperFlags (GDI32.@)
1758 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1760 DC *dc = DC_GetDCPtr( hDC );
1761 DWORD ret = 0;
1762 if(!dc) return 0;
1763 if(dc->funcs->pSetMapperFlags)
1764 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1765 else
1766 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1767 GDI_ReleaseObj( hDC );
1768 return ret;
1771 /***********************************************************************
1772 * GetAspectRatioFilterEx (GDI.486)
1774 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1776 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1777 return FALSE;
1780 /***********************************************************************
1781 * GetAspectRatioFilterEx (GDI32.@)
1783 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1785 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1786 return FALSE;
1789 /***********************************************************************
1790 * GetCharABCWidths (GDI.307)
1792 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1793 LPABC16 abc )
1795 LPABC abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1796 int i;
1798 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1799 HeapFree(GetProcessHeap(),0,abc32);
1800 return FALSE;
1803 for (i=firstChar;i<=lastChar;i++) {
1804 abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1805 abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1806 abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1808 HeapFree(GetProcessHeap(),0,abc32);
1809 return TRUE;
1813 /***********************************************************************
1814 * GetCharABCWidthsA (GDI32.@)
1816 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1817 LPABC abc )
1819 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1820 LPSTR str;
1821 LPWSTR wstr;
1822 BOOL ret = TRUE;
1824 if(count <= 0) return FALSE;
1826 str = HeapAlloc(GetProcessHeap(), 0, count);
1827 for(i = 0; i < count; i++)
1828 str[i] = (BYTE)(firstChar + i);
1830 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1832 for(i = 0; i < wlen; i++)
1834 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1836 ret = FALSE;
1837 break;
1839 abc++;
1842 HeapFree(GetProcessHeap(), 0, str);
1843 HeapFree(GetProcessHeap(), 0, wstr);
1845 return ret;
1849 /******************************************************************************
1850 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1852 * PARAMS
1853 * hdc [I] Handle of device context
1854 * firstChar [I] First character in range to query
1855 * lastChar [I] Last character in range to query
1856 * abc [O] Address of character-width structure
1858 * NOTES
1859 * Only works with TrueType fonts
1861 * RETURNS
1862 * Success: TRUE
1863 * Failure: FALSE
1865 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1866 LPABC abc )
1868 DC *dc = DC_GetDCPtr(hdc);
1869 int i;
1870 GLYPHMETRICS gm;
1871 BOOL ret = FALSE;
1873 if(dc->gdiFont) {
1874 for (i=firstChar;i<=lastChar;i++) {
1875 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1876 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1877 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1878 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1880 ret = TRUE;
1882 GDI_ReleaseObj(hdc);
1883 return ret;
1887 /***********************************************************************
1888 * GetGlyphOutline (GDI.309)
1890 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1891 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1892 LPVOID lpBuffer, const MAT2 *lpmat2 )
1894 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1895 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1896 return (DWORD)-1; /* failure */
1900 /***********************************************************************
1901 * GetGlyphOutlineA (GDI32.@)
1903 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1904 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1905 LPVOID lpBuffer, const MAT2 *lpmat2 )
1907 LPWSTR p = NULL;
1908 DWORD ret;
1909 UINT c;
1911 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1912 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1913 c = p[0];
1914 } else
1915 c = uChar;
1916 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1917 lpmat2);
1918 if(p)
1919 HeapFree(GetProcessHeap(), 0, p);
1920 return ret;
1923 /***********************************************************************
1924 * GetGlyphOutlineW (GDI32.@)
1926 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1927 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1928 LPVOID lpBuffer, const MAT2 *lpmat2 )
1930 DC *dc = DC_GetDCPtr(hdc);
1931 DWORD ret;
1933 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1934 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1936 if(!dc) return GDI_ERROR;
1938 if(dc->gdiFont)
1939 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1940 cbBuffer, lpBuffer, lpmat2);
1941 else
1942 ret = GDI_ERROR;
1944 GDI_ReleaseObj(hdc);
1945 return ret;
1948 /***********************************************************************
1949 * CreateScalableFontResource (GDI.310)
1951 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1952 LPCSTR lpszResourceFile,
1953 LPCSTR fontFile, LPCSTR path )
1955 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1956 fontFile, path );
1959 /***********************************************************************
1960 * CreateScalableFontResourceA (GDI32.@)
1962 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1963 LPCSTR lpszResourceFile,
1964 LPCSTR lpszFontFile,
1965 LPCSTR lpszCurrentPath )
1967 HANDLE f;
1969 /* fHidden=1 - only visible for the calling app, read-only, not
1970 * enumbered with EnumFonts/EnumFontFamilies
1971 * lpszCurrentPath can be NULL
1973 FIXME("(%ld,%s,%s,%s): stub\n",
1974 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1975 debugstr_a(lpszCurrentPath) );
1977 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1978 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1979 CloseHandle(f);
1980 SetLastError(ERROR_FILE_EXISTS);
1981 return FALSE;
1983 return FALSE; /* create failed */
1986 /***********************************************************************
1987 * CreateScalableFontResourceW (GDI32.@)
1989 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1990 LPCWSTR lpszResourceFile,
1991 LPCWSTR lpszFontFile,
1992 LPCWSTR lpszCurrentPath )
1994 FIXME("(%ld,%p,%p,%p): stub\n",
1995 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1996 return FALSE; /* create failed */
2000 /*************************************************************************
2001 * GetRasterizerCaps (GDI.313)
2003 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
2005 return GetRasterizerCaps( lprs, cbNumBytes );
2009 /*************************************************************************
2010 * GetRasterizerCaps (GDI32.@)
2012 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
2014 lprs->nSize = sizeof(RASTERIZER_STATUS);
2015 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
2016 lprs->nLanguageID = 0;
2017 return TRUE;
2021 /*************************************************************************
2022 * GetKerningPairs (GDI.332)
2025 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
2026 LPKERNINGPAIR16 lpKerningPairs )
2028 /* At this time kerning is ignored (set to 0) */
2029 int i;
2030 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2031 if (lpKerningPairs)
2032 for (i = 0; i < cPairs; i++)
2033 lpKerningPairs[i].iKernAmount = 0;
2034 /* FIXME: Should this function call SetLastError (0)? This is yet another
2035 * Microsoft function that can return 0 on success or failure
2037 return 0;
2042 /*************************************************************************
2043 * GetKerningPairsA (GDI32.@)
2045 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
2046 LPKERNINGPAIR lpKerningPairs )
2048 int i;
2049 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2050 for (i = 0; i < cPairs; i++)
2051 lpKerningPairs[i].iKernAmount = 0;
2052 return 0;
2056 /*************************************************************************
2057 * GetKerningPairsW (GDI32.@)
2059 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
2060 LPKERNINGPAIR lpKerningPairs )
2062 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
2065 /*************************************************************************
2066 * TranslateCharsetInfo [GDI32.@]
2067 * TranslateCharsetInfo [USER32.@]
2069 * Fills a CHARSETINFO structure for a character set, code page, or
2070 * font. This allows making the correspondance between different labelings
2071 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
2072 * of the same encoding.
2074 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
2075 * only one codepage should be set in *lpSrc.
2077 * RETURNS
2078 * TRUE on success, FALSE on failure.
2081 BOOL WINAPI TranslateCharsetInfo(
2082 LPDWORD lpSrc, /* [in]
2083 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
2084 if flags == TCI_SRCCHARSET: a character set value
2085 if flags == TCI_SRCCODEPAGE: a code page value
2087 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
2088 DWORD flags /* [in] determines interpretation of lpSrc */
2090 int index = 0;
2091 switch (flags) {
2092 case TCI_SRCFONTSIG:
2093 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
2094 break;
2095 case TCI_SRCCODEPAGE:
2096 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
2097 break;
2098 case TCI_SRCCHARSET:
2099 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
2100 break;
2101 default:
2102 return FALSE;
2104 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
2105 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
2106 return TRUE;
2109 /*************************************************************************
2110 * GetFontLanguageInfo (GDI32.@)
2112 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
2114 FONTSIGNATURE fontsig;
2115 static const DWORD GCP_DBCS_MASK=0x003F0000,
2116 GCP_DIACRITIC_MASK=0x00000000,
2117 FLI_GLYPHS_MASK=0x00000000,
2118 GCP_GLYPHSHAPE_MASK=0x00000040,
2119 GCP_KASHIDA_MASK=0x00000000,
2120 GCP_LIGATE_MASK=0x00000000,
2121 GCP_USEKERNING_MASK=0x00000000,
2122 GCP_REORDER_MASK=0x00000060;
2124 DWORD result=0;
2126 GetTextCharsetInfo( hdc, &fontsig, 0 );
2127 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
2129 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
2130 result|=GCP_DBCS;
2132 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
2133 result|=GCP_DIACRITIC;
2135 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
2136 result|=FLI_GLYPHS;
2138 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
2139 result|=GCP_GLYPHSHAPE;
2141 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
2142 result|=GCP_KASHIDA;
2144 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
2145 result|=GCP_LIGATE;
2147 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
2148 result|=GCP_USEKERNING;
2150 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
2151 result|=GCP_REORDER;
2153 return result;
2156 /*************************************************************************
2157 * GetFontLanguageInfo (GDI.616)
2159 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
2160 /* return value 0 is correct for most cases anyway */
2161 FIXME("(%x):stub!\n",hdc);
2162 return 0;
2165 /*************************************************************************
2166 * GetFontData [GDI32.@] Retrieve data for TrueType font
2168 * RETURNS
2170 * success: Number of bytes returned
2171 * failure: GDI_ERROR
2173 * NOTES
2175 * Calls SetLastError()
2178 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
2179 LPVOID buffer, DWORD length)
2181 DC *dc = DC_GetDCPtr(hdc);
2182 DWORD ret = GDI_ERROR;
2184 if(!dc) return GDI_ERROR;
2186 if(dc->gdiFont)
2187 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
2189 GDI_ReleaseObj(hdc);
2190 return ret;
2193 /*************************************************************************
2194 * GetFontData [GDI.311]
2197 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
2198 LPVOID lpvBuffer, DWORD cbData)
2200 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
2203 /*************************************************************************
2204 * GetGlyphIndicesA [GDI32.@]
2206 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
2207 LPWORD pgi, DWORD flags)
2209 DWORD ret;
2210 WCHAR *lpstrW;
2211 INT countW;
2213 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2214 hdc, debugstr_an(lpstr, count), count, pgi, flags);
2216 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
2217 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
2218 HeapFree(GetProcessHeap(), 0, lpstrW);
2220 return ret;
2223 /*************************************************************************
2224 * GetGlyphIndicesW [GDI32.@]
2226 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
2227 LPWORD pgi, DWORD flags)
2229 DC *dc = DC_GetDCPtr(hdc);
2230 DWORD ret = GDI_ERROR;
2232 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2233 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2235 if(!dc) return GDI_ERROR;
2237 if(dc->gdiFont)
2238 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
2240 GDI_ReleaseObj(hdc);
2241 return ret;
2244 /*************************************************************************
2245 * GetCharacterPlacementA [GDI32.@]
2247 * NOTES:
2248 * the web browser control of ie4 calls this with dwFlags=0
2250 DWORD WINAPI
2251 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2252 INT nMaxExtent, GCP_RESULTSA *lpResults,
2253 DWORD dwFlags)
2255 WCHAR *lpStringW;
2256 INT uCountW, i;
2257 GCP_RESULTSW resultsW;
2258 DWORD ret;
2259 UINT font_cp;
2261 TRACE("%s, %d, %d, 0x%08lx\n",
2262 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2264 /* both structs are equal in size */
2265 memcpy(&resultsW, lpResults, sizeof(resultsW));
2267 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2268 if( dwFlags&GCP_REORDER )
2270 /* If the REORDER flag is not set, this field is ignored anyways */
2271 if(lpResults->lpOutString)
2272 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
2273 else
2274 resultsW.lpOutString = NULL;
2277 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2279 if(lpResults->lpOutString) {
2280 if(font_cp != CP_SYMBOL)
2281 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2282 lpResults->lpOutString, uCount, NULL, NULL );
2283 else
2284 for(i = 0; i < uCount; i++)
2285 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
2288 HeapFree(GetProcessHeap(), 0, lpStringW);
2289 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2291 return ret;
2294 /*************************************************************************
2295 * GetCharacterPlacementW [GDI32.@]
2297 * Retrieve information about a string. This includes the width, reordering,
2298 * Glyphing and so on.
2300 * RETURNS
2302 * The width and height of the string if succesful, 0 if failed.
2304 * BUGS
2306 * All flags except GCP_REORDER are not yet implemented.
2307 * Reordering is not 100% complient to the Windows BiDi method.
2308 * Caret positioning is not yet implemented.
2309 * Classes are not yet implemented.
2312 DWORD WINAPI
2313 GetCharacterPlacementW(
2314 HDC hdc, /* [in] Device context for which the rendering is to be done */
2315 LPCWSTR lpString, /* [in] The string for which information is to be returned */
2316 INT uCount, /* [in] Number of WORDS in string. */
2317 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
2318 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
2319 DWORD dwFlags /* [in] Flags specifying how to process the string */
2322 DWORD ret=0;
2323 SIZE size;
2324 UINT i, nSet;
2326 TRACE("%s, %d, %d, 0x%08lx\n",
2327 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2329 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2330 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2331 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2332 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2333 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2335 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
2336 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2337 if(lpResults->lpClass) FIXME("classes not implemented\n");
2339 nSet = (UINT)uCount;
2340 if(nSet > lpResults->nGlyphs)
2341 nSet = lpResults->nGlyphs;
2343 /* return number of initialized fields */
2344 lpResults->nGlyphs = nSet;
2346 if((dwFlags&GCP_REORDER)!=0)
2348 /* MSDN says lpOutString and lpOrder are ignored if GCP_REORDER not set */
2349 WORD *pwCharType;
2350 int run_end;
2351 /* Keep a static table that translates the C2 types to something meaningful */
2352 /* 1 - left to right
2353 * -1 - right to left
2354 * 0 - neutral
2356 static const int chardir[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
2358 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
2359 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
2361 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2363 return 0;
2366 /* Fill in the order array with directionality values */
2367 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2369 /* The complete and correct (at least according to MS) BiDi algorythm is not
2370 * yet implemented here. Instead, we just make sure that consecutive runs of
2371 * the same direction (or neutral) are ordered correctly
2373 for( i=0; i<uCount; i+=run_end )
2375 for( run_end=1; i+run_end<uCount &&
2376 (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2377 chardir[pwCharType[i+run_end]]==0); ++run_end )
2380 if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2382 /* A LTR run */
2383 if(lpResults->lpOutString)
2385 int j;
2386 for( j=0; j<run_end; j++ )
2388 lpResults->lpOutString[i+j]=lpString[i+j];
2392 if(lpResults->lpOrder)
2394 int j;
2395 for( j=0; j<run_end; j++ )
2396 lpResults->lpOrder[i+j] = i+j;
2398 } else
2400 /* A RTL run */
2401 if(lpResults->lpOutString)
2403 int j;
2404 for( j=0; j<run_end; j++ )
2406 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2410 if(lpResults->lpOrder)
2412 int j;
2413 for( j=0; j<run_end; j++ )
2414 lpResults->lpOrder[i+j] = i+run_end-j-1;
2419 HeapFree(GetProcessHeap(), 0, pwCharType);
2422 /* FIXME: Will use the placement chars */
2423 if (lpResults->lpDx)
2425 int c;
2426 for (i = 0; i < nSet; i++)
2428 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2429 lpResults->lpDx[i]= c;
2433 if(lpResults->lpGlyphs)
2434 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2436 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2437 ret = MAKELONG(size.cx, size.cy);
2439 return ret;
2442 /*************************************************************************
2443 * GetCharABCWidthsFloatA [GDI32.@]
2445 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2446 LPABCFLOAT lpABCF)
2448 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2449 return 0;
2452 /*************************************************************************
2453 * GetCharABCWidthsFloatW [GDI32.@]
2455 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2456 UINT iLastChar, LPABCFLOAT lpABCF)
2458 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2459 return 0;
2462 /*************************************************************************
2463 * GetCharWidthFloatA [GDI32.@]
2465 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2466 UINT iLastChar, PFLOAT pxBuffer)
2468 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2469 return 0;
2472 /*************************************************************************
2473 * GetCharWidthFloatW [GDI32.@]
2475 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2476 UINT iLastChar, PFLOAT pxBuffer)
2478 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2479 return 0;
2483 /***********************************************************************
2485 * Font Resource API *
2487 ***********************************************************************/
2488 /***********************************************************************
2489 * AddFontResource (GDI.119)
2491 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2494 INT16 WINAPI AddFontResource16( LPCSTR filename )
2496 return AddFontResourceA( filename );
2499 /***********************************************************************
2500 * AddFontResourceA (GDI32.@)
2502 INT WINAPI AddFontResourceA( LPCSTR str )
2504 return AddFontResourceExA( str, 0, NULL);
2507 /***********************************************************************
2508 * AddFontResourceW (GDI32.@)
2510 INT WINAPI AddFontResourceW( LPCWSTR str )
2512 return AddFontResourceExW(str, 0, NULL);
2516 /***********************************************************************
2517 * AddFontResourceExA (GDI32.@)
2519 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2521 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2522 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2523 INT ret;
2525 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2526 ret = AddFontResourceExW(strW, fl, pdv);
2527 HeapFree(GetProcessHeap(), 0, strW);
2528 return ret;
2531 /***********************************************************************
2532 * AddFontResourceExW (GDI32.@)
2534 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2536 return WineEngAddFontResourceEx(str, fl, pdv);
2539 /***********************************************************************
2540 * RemoveFontResource (GDI.136)
2542 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2544 return RemoveFontResourceA(str);
2547 /***********************************************************************
2548 * RemoveFontResourceA (GDI32.@)
2550 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2552 return RemoveFontResourceExA(str, 0, 0);
2555 /***********************************************************************
2556 * RemoveFontResourceW (GDI32.@)
2558 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2560 return RemoveFontResourceExW(str, 0, 0);
2563 /***********************************************************************
2564 * RemoveFontResourceExA (GDI32.@)
2566 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2568 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2569 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2570 INT ret;
2572 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2573 ret = RemoveFontResourceExW(strW, fl, pdv);
2574 HeapFree(GetProcessHeap(), 0, strW);
2575 return ret;
2578 /***********************************************************************
2579 * RemoveFontResourceExW (GDI32.@)
2581 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2583 return WineEngRemoveFontResourceEx(str, fl, pdv);