Added a GNU C implementation of some of the DECLSPEC_ macros and used
[wine/hacks.git] / objects / font.c
blob55bc4f21f579a1b6ddb2244cb0e9f5c0d8c05c8c
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 "config.h"
23 #include "wine/port.h"
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28 #include "winerror.h"
29 #include "winnls.h"
30 #include "wine/unicode.h"
31 #include "font.h"
32 #include "wine/debug.h"
33 #include "gdi.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(font);
36 WINE_DECLARE_DEBUG_CHANNEL(gdi);
38 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
39 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
40 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
41 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
44 static const struct gdi_obj_funcs font_funcs =
46 FONT_SelectObject, /* pSelectObject */
47 FONT_GetObject16, /* pGetObject16 */
48 FONT_GetObjectA, /* pGetObjectA */
49 FONT_GetObjectW, /* pGetObjectW */
50 NULL, /* pUnrealizeObject */
51 FONT_DeleteObject /* pDeleteObject */
54 #define ENUM_UNICODE 0x00000001
55 #define ENUM_CALLED 0x00000002
57 typedef struct
59 GDIOBJHDR header;
60 LOGFONTW logfont;
61 } FONTOBJ;
63 typedef struct
65 LPLOGFONT16 lpLogFontParam;
66 FONTENUMPROCEX16 lpEnumFunc;
67 LPARAM lpData;
69 LPNEWTEXTMETRICEX16 lpTextMetric;
70 LPENUMLOGFONTEX16 lpLogFont;
71 SEGPTR segTextMetric;
72 SEGPTR segLogFont;
73 HDC hdc;
74 DC *dc;
75 PHYSDEV physDev;
76 } fontEnum16;
78 typedef struct
80 LPLOGFONTW lpLogFontParam;
81 FONTENUMPROCEXW lpEnumFunc;
82 LPARAM lpData;
83 DWORD dwFlags;
84 HDC hdc;
85 DC *dc;
86 PHYSDEV physDev;
87 } fontEnum32;
90 * For TranslateCharsetInfo
92 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
93 #define MAXTCIINDEX 32
94 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
95 /* ANSI */
96 { ANSI_CHARSET, 1252, FS(0)},
97 { EASTEUROPE_CHARSET, 1250, FS(1)},
98 { RUSSIAN_CHARSET, 1251, FS(2)},
99 { GREEK_CHARSET, 1253, FS(3)},
100 { TURKISH_CHARSET, 1254, FS(4)},
101 { HEBREW_CHARSET, 1255, FS(5)},
102 { ARABIC_CHARSET, 1256, FS(6)},
103 { BALTIC_CHARSET, 1257, FS(7)},
104 { VIETNAMESE_CHARSET, 1258, FS(8)},
105 /* reserved by ANSI */
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 { DEFAULT_CHARSET, 0, FS(0)},
111 { DEFAULT_CHARSET, 0, FS(0)},
112 { DEFAULT_CHARSET, 0, FS(0)},
113 /* ANSI and OEM */
114 { THAI_CHARSET, 874, FS(16)},
115 { SHIFTJIS_CHARSET, 932, FS(17)},
116 { GB2312_CHARSET, 936, FS(18)},
117 { HANGEUL_CHARSET, 949, FS(19)},
118 { CHINESEBIG5_CHARSET, 950, FS(20)},
119 { JOHAB_CHARSET, 1361, FS(21)},
120 /* reserved for alternate ANSI and OEM */
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 { DEFAULT_CHARSET, 0, FS(0)},
127 { DEFAULT_CHARSET, 0, FS(0)},
128 { DEFAULT_CHARSET, 0, FS(0)},
129 /* reserved for system */
130 { DEFAULT_CHARSET, 0, FS(0)},
131 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
134 /* ### start build ### */
135 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROCEX16,LONG,LONG,WORD,LONG);
136 /* ### stop build ### */
138 /***********************************************************************
139 * LOGFONT conversion functions.
141 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
143 font16->lfHeight = font32->lfHeight;
144 font16->lfWidth = font32->lfWidth;
145 font16->lfEscapement = font32->lfEscapement;
146 font16->lfOrientation = font32->lfOrientation;
147 font16->lfWeight = font32->lfWeight;
148 font16->lfItalic = font32->lfItalic;
149 font16->lfUnderline = font32->lfUnderline;
150 font16->lfStrikeOut = font32->lfStrikeOut;
151 font16->lfCharSet = font32->lfCharSet;
152 font16->lfOutPrecision = font32->lfOutPrecision;
153 font16->lfClipPrecision = font32->lfClipPrecision;
154 font16->lfQuality = font32->lfQuality;
155 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
156 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
157 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
158 font16->lfFaceName[LF_FACESIZE-1] = 0;
161 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
163 font32->lfHeight = font16->lfHeight;
164 font32->lfWidth = font16->lfWidth;
165 font32->lfEscapement = font16->lfEscapement;
166 font32->lfOrientation = font16->lfOrientation;
167 font32->lfWeight = font16->lfWeight;
168 font32->lfItalic = font16->lfItalic;
169 font32->lfUnderline = font16->lfUnderline;
170 font32->lfStrikeOut = font16->lfStrikeOut;
171 font32->lfCharSet = font16->lfCharSet;
172 font32->lfOutPrecision = font16->lfOutPrecision;
173 font32->lfClipPrecision = font16->lfClipPrecision;
174 font32->lfQuality = font16->lfQuality;
175 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
176 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
177 font32->lfFaceName[LF_FACESIZE-1] = 0;
180 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
182 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
183 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
184 LF_FACESIZE);
187 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
189 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
190 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
191 LF_FACESIZE, NULL, NULL);
194 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
196 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
198 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
199 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
200 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
201 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
202 font16->elfStyle, LF_FACESIZE, NULL, NULL );
203 font16->elfStyle[LF_FACESIZE-1] = '\0';
204 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
205 font16->elfScript, LF_FACESIZE, NULL, NULL );
206 font16->elfScript[LF_FACESIZE-1] = '\0';
209 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
211 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
213 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
214 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
215 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
216 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
217 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
218 fontA->elfStyle[LF_FACESIZE-1] = '\0';
219 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
220 fontA->elfScript, LF_FACESIZE, NULL, NULL );
221 fontA->elfScript[LF_FACESIZE-1] = '\0';
224 /***********************************************************************
225 * TEXTMETRIC conversion functions.
227 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
229 ptmA->tmHeight = ptmW->tmHeight;
230 ptmA->tmAscent = ptmW->tmAscent;
231 ptmA->tmDescent = ptmW->tmDescent;
232 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
233 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
234 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
235 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
236 ptmA->tmWeight = ptmW->tmWeight;
237 ptmA->tmOverhang = ptmW->tmOverhang;
238 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
239 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
240 ptmA->tmFirstChar = ptmW->tmFirstChar;
241 ptmA->tmLastChar = ptmW->tmLastChar;
242 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
243 ptmA->tmBreakChar = ptmW->tmBreakChar;
244 ptmA->tmItalic = ptmW->tmItalic;
245 ptmA->tmUnderlined = ptmW->tmUnderlined;
246 ptmA->tmStruckOut = ptmW->tmStruckOut;
247 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
248 ptmA->tmCharSet = ptmW->tmCharSet;
252 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
254 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
255 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
256 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
257 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
258 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
259 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
260 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
261 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
262 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
263 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
264 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
265 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar;
266 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
267 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
268 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar;
269 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
270 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
271 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
272 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
273 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
274 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
275 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
276 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
277 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
278 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
281 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
283 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
284 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
285 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
286 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
287 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
288 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
291 /***********************************************************************
292 * CreateFontIndirectA (GDI32.@)
294 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
296 LOGFONTW lfW;
298 if (plfA) {
299 FONT_LogFontAToW( plfA, &lfW );
300 return CreateFontIndirectW( &lfW );
301 } else
302 return CreateFontIndirectW( NULL );
306 /***********************************************************************
307 * CreateFontIndirectW (GDI32.@)
309 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
311 HFONT hFont = 0;
313 if (plf)
315 FONTOBJ* fontPtr;
316 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont, &font_funcs )))
318 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
320 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
321 plf->lfHeight, plf->lfWidth,
322 plf->lfEscapement, plf->lfOrientation,
323 plf->lfPitchAndFamily,
324 debugstr_w(plf->lfFaceName),
325 plf->lfWeight > 400 ? "Bold" : "",
326 plf->lfItalic ? "Italic" : "", hFont);
328 if (plf->lfEscapement != plf->lfOrientation) {
329 /* this should really depend on whether GM_ADVANCED is set */
330 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
331 WARN("orientation angle %f set to "
332 "escapement angle %f for new font %04x\n",
333 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
335 GDI_ReleaseObj( hFont );
338 else WARN("(NULL) => NULL\n");
340 return hFont;
343 /***********************************************************************
344 * CreateFont (GDI.56)
346 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
347 INT16 weight, BYTE italic, BYTE underline,
348 BYTE strikeout, BYTE charset, BYTE outpres,
349 BYTE clippres, BYTE quality, BYTE pitch,
350 LPCSTR name )
352 LOGFONT16 logfont;
354 logfont.lfHeight = height;
355 logfont.lfWidth = width;
356 logfont.lfEscapement = esc;
357 logfont.lfOrientation = orient;
358 logfont.lfWeight = weight;
359 logfont.lfItalic = italic;
360 logfont.lfUnderline = underline;
361 logfont.lfStrikeOut = strikeout;
362 logfont.lfCharSet = charset;
363 logfont.lfOutPrecision = outpres;
364 logfont.lfClipPrecision = clippres;
365 logfont.lfQuality = quality;
366 logfont.lfPitchAndFamily = pitch;
368 if (name)
369 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
370 else
371 logfont.lfFaceName[0] = '\0';
373 return CreateFontIndirect16( &logfont );
376 /*************************************************************************
377 * CreateFontA (GDI32.@)
379 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
380 INT orient, INT weight, DWORD italic,
381 DWORD underline, DWORD strikeout, DWORD charset,
382 DWORD outpres, DWORD clippres, DWORD quality,
383 DWORD pitch, LPCSTR name )
385 LOGFONTA logfont;
387 logfont.lfHeight = height;
388 logfont.lfWidth = width;
389 logfont.lfEscapement = esc;
390 logfont.lfOrientation = orient;
391 logfont.lfWeight = weight;
392 logfont.lfItalic = italic;
393 logfont.lfUnderline = underline;
394 logfont.lfStrikeOut = strikeout;
395 logfont.lfCharSet = charset;
396 logfont.lfOutPrecision = outpres;
397 logfont.lfClipPrecision = clippres;
398 logfont.lfQuality = quality;
399 logfont.lfPitchAndFamily = pitch;
401 if (name)
402 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
403 else
404 logfont.lfFaceName[0] = '\0';
406 return CreateFontIndirectA( &logfont );
409 /*************************************************************************
410 * CreateFontW (GDI32.@)
412 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
413 INT orient, INT weight, DWORD italic,
414 DWORD underline, DWORD strikeout, DWORD charset,
415 DWORD outpres, DWORD clippres, DWORD quality,
416 DWORD pitch, LPCWSTR name )
418 LOGFONTW logfont;
420 logfont.lfHeight = height;
421 logfont.lfWidth = width;
422 logfont.lfEscapement = esc;
423 logfont.lfOrientation = orient;
424 logfont.lfWeight = weight;
425 logfont.lfItalic = italic;
426 logfont.lfUnderline = underline;
427 logfont.lfStrikeOut = strikeout;
428 logfont.lfCharSet = charset;
429 logfont.lfOutPrecision = outpres;
430 logfont.lfClipPrecision = clippres;
431 logfont.lfQuality = quality;
432 logfont.lfPitchAndFamily = pitch;
434 if (name)
435 lstrcpynW(logfont.lfFaceName, name,
436 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
437 else
438 logfont.lfFaceName[0] = '\0';
440 return CreateFontIndirectW( &logfont );
444 /***********************************************************************
445 * FONT_SelectObject
447 * If the driver supports vector fonts we create a gdi font first and
448 * then call the driver to give it a chance to supply its own device
449 * font. If the driver wants to do this it returns TRUE and we can
450 * delete the gdi font, if the driver wants to use the gdi font it
451 * should return FALSE, to signal an error return GDI_ERROR. For
452 * drivers that don't support vector fonts they must supply their own
453 * font.
455 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
457 HGDIOBJ ret = 0;
458 DC *dc = DC_GetDCPtr( hdc );
460 if (!dc) return 0;
462 if (dc->hFont != handle || dc->gdiFont == NULL)
464 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
465 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
468 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
470 if (ret && dc->gdiFont) dc->gdiFont = 0;
472 if (ret == GDI_ERROR)
473 ret = 0; /* SelectObject returns 0 on error */
474 else
476 ret = dc->hFont;
477 dc->hFont = handle;
479 GDI_ReleaseObj( hdc );
480 return ret;
484 /***********************************************************************
485 * FONT_GetObject16
487 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
489 FONTOBJ *font = obj;
490 LOGFONT16 lf16;
492 FONT_LogFontWTo16( &font->logfont, &lf16 );
494 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
495 memcpy( buffer, &lf16, count );
496 return count;
499 /***********************************************************************
500 * FONT_GetObjectA
502 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
504 FONTOBJ *font = obj;
505 LOGFONTA lfA;
507 FONT_LogFontWToA( &font->logfont, &lfA );
509 if (count > sizeof(lfA)) count = sizeof(lfA);
510 if(buffer)
511 memcpy( buffer, &lfA, count );
512 return count;
515 /***********************************************************************
516 * FONT_GetObjectW
518 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
520 FONTOBJ *font = obj;
521 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
522 if(buffer)
523 memcpy( buffer, &font->logfont, count );
524 return count;
528 /***********************************************************************
529 * FONT_DeleteObject
531 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
533 WineEngDestroyFontInstance( handle );
534 return GDI_FreeObject( handle, obj );
538 /***********************************************************************
539 * FONT_EnumInstance16
541 * Called by the device driver layer to pass font info
542 * down to the application.
544 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
545 DWORD fType, LPARAM lp )
547 fontEnum16 *pfe = (fontEnum16*)lp;
548 INT ret = 1;
549 DC *dc;
551 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
552 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
554 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
555 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
556 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
558 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
559 (UINT16)fType, (LPARAM)pfe->lpData );
560 /* get the lock again and make sure the DC is still valid */
561 dc = DC_GetDCPtr( pfe->hdc );
562 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
564 if (dc) GDI_ReleaseObj( pfe->hdc );
565 pfe->hdc = 0; /* make sure we don't try to release it later on */
566 ret = 0;
569 return ret;
572 /***********************************************************************
573 * FONT_EnumInstance
575 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
576 DWORD fType, LPARAM lp )
578 fontEnum32 *pfe = (fontEnum32*)lp;
579 INT ret = 1;
580 DC *dc;
582 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
583 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
584 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
586 /* convert font metrics */
587 ENUMLOGFONTEXA logfont;
588 NEWTEXTMETRICEXA tmA;
590 pfe->dwFlags |= ENUM_CALLED;
591 if (!(pfe->dwFlags & ENUM_UNICODE))
593 FONT_EnumLogFontExWToA( plf, &logfont);
594 FONT_NewTextMetricExWToA( ptm, &tmA );
595 plf = (LPENUMLOGFONTEXW)&logfont;
596 ptm = (LPNEWTEXTMETRICEXW)&tmA;
598 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
600 ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
602 /* get the lock again and make sure the DC is still valid */
603 dc = DC_GetDCPtr( pfe->hdc );
604 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
606 if (dc) GDI_ReleaseObj( pfe->hdc );
607 pfe->hdc = 0; /* make sure we don't try to release it later on */
608 ret = 0;
611 return ret;
614 /***********************************************************************
615 * EnumFontFamiliesEx (GDI.613)
617 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
618 FONTENUMPROCEX16 efproc, LPARAM lParam,
619 DWORD dwFlags)
621 fontEnum16 fe16;
622 INT16 retVal = 0;
623 DC* dc = DC_GetDCPtr( hDC );
625 if (!dc) return 0;
626 fe16.hdc = hDC;
627 fe16.dc = dc;
628 fe16.physDev = dc->physDev;
630 if (dc->funcs->pEnumDeviceFonts)
632 NEWTEXTMETRICEX16 tm16;
633 ENUMLOGFONTEX16 lf16;
634 LOGFONTW lfW;
635 FONT_LogFont16ToW(plf, &lfW);
637 fe16.lpLogFontParam = plf;
638 fe16.lpEnumFunc = efproc;
639 fe16.lpData = lParam;
640 fe16.lpTextMetric = &tm16;
641 fe16.lpLogFont = &lf16;
642 fe16.segTextMetric = MapLS( &tm16 );
643 fe16.segLogFont = MapLS( &lf16 );
645 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
646 FONT_EnumInstance16, (LPARAM)&fe16 );
647 UnMapLS( fe16.segTextMetric );
648 UnMapLS( fe16.segLogFont );
650 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
651 return retVal;
654 /***********************************************************************
655 * FONT_EnumFontFamiliesEx
657 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
658 FONTENUMPROCEXW efproc,
659 LPARAM lParam, DWORD dwUnicode)
661 INT ret = 1, ret2;
662 DC *dc = DC_GetDCPtr( hDC );
663 fontEnum32 fe32;
664 BOOL enum_gdi_fonts;
666 if (!dc) return 0;
668 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
669 plf->lfCharSet);
670 fe32.lpLogFontParam = plf;
671 fe32.lpEnumFunc = efproc;
672 fe32.lpData = lParam;
673 fe32.dwFlags = dwUnicode;
674 fe32.hdc = hDC;
675 fe32.dc = dc;
676 fe32.physDev = dc->physDev;
678 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
680 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
682 ret = 0;
683 goto done;
686 if (enum_gdi_fonts)
687 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
688 fe32.dwFlags &= ~ENUM_CALLED;
689 if (ret && dc->funcs->pEnumDeviceFonts) {
690 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
691 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
692 ret = ret2;
694 done:
695 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
696 return ret;
699 /***********************************************************************
700 * EnumFontFamiliesExW (GDI32.@)
702 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
703 FONTENUMPROCEXW efproc,
704 LPARAM lParam, DWORD dwFlags )
706 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
709 /***********************************************************************
710 * EnumFontFamiliesExA (GDI32.@)
712 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
713 FONTENUMPROCEXA efproc,
714 LPARAM lParam, DWORD dwFlags)
716 LOGFONTW lfW;
717 FONT_LogFontAToW( plf, &lfW );
719 return FONT_EnumFontFamiliesEx( hDC, &lfW,
720 (FONTENUMPROCEXW)efproc, lParam, 0);
723 /***********************************************************************
724 * EnumFontFamilies (GDI.330)
726 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
727 FONTENUMPROC16 efproc, LPARAM lpData )
729 LOGFONT16 lf;
731 lf.lfCharSet = DEFAULT_CHARSET;
732 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
733 else lf.lfFaceName[0] = '\0';
735 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
738 /***********************************************************************
739 * EnumFontFamiliesA (GDI32.@)
741 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
742 FONTENUMPROCA efproc, LPARAM lpData )
744 LOGFONTA lf;
746 lf.lfCharSet = DEFAULT_CHARSET;
747 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
748 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
750 return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
753 /***********************************************************************
754 * EnumFontFamiliesW (GDI32.@)
756 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
757 FONTENUMPROCW efproc, LPARAM lpData )
759 LOGFONTW lf;
761 lf.lfCharSet = DEFAULT_CHARSET;
762 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
763 else lf.lfFaceName[0] = 0;
765 return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
768 /***********************************************************************
769 * EnumFonts (GDI.70)
771 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
772 LPARAM lpData )
774 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
777 /***********************************************************************
778 * EnumFontsA (GDI32.@)
780 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
781 LPARAM lpData )
783 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
786 /***********************************************************************
787 * EnumFontsW (GDI32.@)
789 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
790 LPARAM lpData )
792 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
796 /***********************************************************************
797 * GetTextCharacterExtra (GDI32.@)
799 INT WINAPI GetTextCharacterExtra( HDC hdc )
801 INT ret;
802 DC *dc = DC_GetDCPtr( hdc );
803 if (!dc) return 0;
804 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
805 / dc->vportExtX );
806 GDI_ReleaseObj( hdc );
807 return ret;
811 /***********************************************************************
812 * SetTextCharacterExtra (GDI32.@)
814 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
816 INT prev;
817 DC * dc = DC_GetDCPtr( hdc );
818 if (!dc) return 0;
819 if (dc->funcs->pSetTextCharacterExtra)
820 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
821 else
823 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
824 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
825 dc->charExtra = abs(extra);
827 GDI_ReleaseObj( hdc );
828 return prev;
832 /***********************************************************************
833 * SetTextJustification (GDI32.@)
835 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
837 BOOL ret = TRUE;
838 DC * dc = DC_GetDCPtr( hdc );
839 if (!dc) return FALSE;
840 if (dc->funcs->pSetTextJustification)
841 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
842 else
844 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
845 if (!extra) breaks = 0;
846 dc->breakTotalExtra = extra;
847 dc->breakCount = breaks;
848 if (breaks)
850 dc->breakExtra = extra / breaks;
851 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
853 else
855 dc->breakExtra = 0;
856 dc->breakRem = 0;
859 GDI_ReleaseObj( hdc );
860 return ret;
864 /***********************************************************************
865 * GetTextFaceA (GDI32.@)
867 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
869 INT res = GetTextFaceW(hdc, 0, NULL);
870 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
871 GetTextFaceW( hdc, res, nameW );
873 if (name)
874 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
875 NULL, NULL);
876 else
877 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
878 HeapFree( GetProcessHeap(), 0, nameW );
879 return res;
882 /***********************************************************************
883 * GetTextFaceW (GDI32.@)
885 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
887 FONTOBJ *font;
888 INT ret = 0;
890 DC * dc = DC_GetDCPtr( hdc );
891 if (!dc) return 0;
893 if(dc->gdiFont)
894 ret = WineEngGetTextFace(dc->gdiFont, count, name);
895 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
897 if (name)
899 lstrcpynW( name, font->logfont.lfFaceName, count );
900 ret = strlenW(name);
902 else ret = strlenW(font->logfont.lfFaceName) + 1;
903 GDI_ReleaseObj( dc->hFont );
905 GDI_ReleaseObj( hdc );
906 return ret;
910 /***********************************************************************
911 * GetTextExtentPoint32A (GDI32.@)
913 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
914 LPSIZE size )
916 BOOL ret = FALSE;
917 INT wlen;
918 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
920 if (p) {
921 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
922 HeapFree( GetProcessHeap(), 0, p );
925 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
926 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
927 return ret;
931 /***********************************************************************
932 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
934 * Computes width and height of the specified string.
936 * RETURNS
937 * Success: TRUE
938 * Failure: FALSE
940 BOOL WINAPI GetTextExtentPoint32W(
941 HDC hdc, /* [in] Handle of device context */
942 LPCWSTR str, /* [in] Address of text string */
943 INT count, /* [in] Number of characters in string */
944 LPSIZE size) /* [out] Address of structure for string size */
946 BOOL ret = FALSE;
947 DC * dc = DC_GetDCPtr( hdc );
948 if (!dc) return FALSE;
950 if(dc->gdiFont) {
951 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
952 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
953 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
955 else if(dc->funcs->pGetTextExtentPoint)
956 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
958 GDI_ReleaseObj( hdc );
960 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
961 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
962 return ret;
965 /***********************************************************************
966 * GetTextExtentPointI [GDI32.@]
968 * Computes width and height of the array of glyph indices.
970 * RETURNS
971 * Success: TRUE
972 * Failure: FALSE
974 BOOL WINAPI GetTextExtentPointI(
975 HDC hdc, /* [in] Handle of device context */
976 const WORD *indices, /* [in] Address of glyph index array */
977 INT count, /* [in] Number of glyphs in array */
978 LPSIZE size) /* [out] Address of structure for string size */
980 BOOL ret = FALSE;
981 DC * dc = DC_GetDCPtr( hdc );
982 if (!dc) return FALSE;
984 if(dc->gdiFont) {
985 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
986 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
987 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
989 else if(dc->funcs->pGetTextExtentPoint) {
990 FIXME("calling GetTextExtentPoint\n");
991 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
994 GDI_ReleaseObj( hdc );
996 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
997 hdc, indices, count, size, size->cx, size->cy );
998 return ret;
1002 /***********************************************************************
1003 * GetTextExtentPointA (GDI32.@)
1005 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1006 LPSIZE size )
1008 TRACE("not bug compatible.\n");
1009 return GetTextExtentPoint32A( hdc, str, count, size );
1012 /***********************************************************************
1013 * GetTextExtentPointW (GDI32.@)
1015 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1016 LPSIZE size )
1018 TRACE("not bug compatible.\n");
1019 return GetTextExtentPoint32W( hdc, str, count, size );
1023 /***********************************************************************
1024 * GetTextExtentExPointA (GDI32.@)
1026 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1027 INT maxExt, LPINT lpnFit,
1028 LPINT alpDx, LPSIZE size )
1030 BOOL ret;
1031 INT wlen;
1032 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1033 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1034 HeapFree( GetProcessHeap(), 0, p );
1035 return ret;
1039 /***********************************************************************
1040 * GetTextExtentExPointW (GDI32.@)
1042 * Return the size of the string as it would be if it was output properly by
1043 * e.g. TextOut.
1045 * This should include
1046 * - Intercharacter spacing
1047 * - justification spacing (not yet done)
1048 * - kerning? see below
1050 * Kerning. Since kerning would be carried out by the rendering code it should
1051 * be done by the driver. However they don't support it yet. Also I am not
1052 * yet persuaded that (certainly under Win95) any kerning is actually done.
1054 * str: According to MSDN this should be null-terminated. That is not true; a
1055 * null will not terminate it early.
1056 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1057 * than count. I have seen it be either the size of the full string or
1058 * 1 less than the size of the full string. I have not seen it bear any
1059 * resemblance to the portion that would fit.
1060 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1061 * trailing intercharacter spacing and any trailing justification.
1063 * FIXME
1064 * Currently we do this by measuring each character etc. We should do it by
1065 * passing the request to the driver, perhaps by extending the
1066 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1067 * thinking about kerning issues and rounding issues in the justification.
1070 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1071 INT maxExt, LPINT lpnFit,
1072 LPINT alpDx, LPSIZE size )
1074 int index, nFit, extent;
1075 SIZE tSize;
1076 BOOL ret = FALSE;
1078 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1080 size->cx = size->cy = nFit = extent = 0;
1081 for(index = 0; index < count; index++)
1083 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1084 /* GetTextExtentPoint includes intercharacter spacing. */
1085 /* FIXME - justification needs doing yet. Remember that the base
1086 * data will not be in logical coordinates.
1088 extent += tSize.cx;
1089 if( !lpnFit || extent <= maxExt )
1090 /* It is allowed to be equal. */
1092 nFit++;
1093 if( alpDx ) alpDx[index] = extent;
1095 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1096 str++;
1098 size->cx = extent;
1099 if(lpnFit) *lpnFit = nFit;
1100 ret = TRUE;
1102 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1104 done:
1105 return ret;
1108 /***********************************************************************
1109 * GetTextMetricsA (GDI32.@)
1111 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1113 TEXTMETRICW tm32;
1115 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1116 FONT_TextMetricWToA( &tm32, metrics );
1117 return TRUE;
1120 /***********************************************************************
1121 * GetTextMetricsW (GDI32.@)
1123 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1125 BOOL ret = FALSE;
1126 DC * dc = DC_GetDCPtr( hdc );
1127 if (!dc) return FALSE;
1129 if (dc->gdiFont)
1130 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1131 else if (dc->funcs->pGetTextMetrics)
1132 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1134 if (ret)
1136 /* device layer returns values in device units
1137 * therefore we have to convert them to logical */
1139 #define WDPTOLP(x) ((x<0)? \
1140 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1141 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1142 #define HDPTOLP(y) ((y<0)? \
1143 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1144 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1146 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1147 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1148 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1149 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1150 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1151 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1152 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1153 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1154 ret = TRUE;
1155 #undef WDPTOLP
1156 #undef HDPTOLP
1157 TRACE("text metrics:\n"
1158 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1159 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1160 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1161 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1162 " PitchAndFamily = %02x\n"
1163 " --------------------\n"
1164 " InternalLeading = %li\n"
1165 " Ascent = %li\n"
1166 " Descent = %li\n"
1167 " Height = %li\n",
1168 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1169 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1170 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1171 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1172 metrics->tmPitchAndFamily,
1173 metrics->tmInternalLeading,
1174 metrics->tmAscent,
1175 metrics->tmDescent,
1176 metrics->tmHeight );
1178 GDI_ReleaseObj( hdc );
1179 return ret;
1183 /***********************************************************************
1184 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1186 * NOTES
1187 * lpOTM should be LPOUTLINETEXTMETRIC
1189 * RETURNS
1190 * Success: Non-zero or size of required buffer
1191 * Failure: 0
1193 UINT16 WINAPI GetOutlineTextMetrics16(
1194 HDC16 hdc, /* [in] Handle of device context */
1195 UINT16 cbData, /* [in] Size of metric data array */
1196 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1198 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1199 return 0;
1203 /***********************************************************************
1204 * GetOutlineTextMetricsA (GDI32.@)
1205 * Gets metrics for TrueType fonts.
1208 * RETURNS
1209 * Success: Non-zero or size of required buffer
1210 * Failure: 0
1212 UINT WINAPI GetOutlineTextMetricsA(
1213 HDC hdc, /* [in] Handle of device context */
1214 UINT cbData, /* [in] Size of metric data array */
1215 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1217 char buf[512], *ptr;
1218 UINT ret, needed;
1219 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1220 INT left, len;
1222 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1223 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1224 return 0;
1225 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1226 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1229 needed = sizeof(OUTLINETEXTMETRICA);
1230 if(lpOTMW->otmpFamilyName)
1231 needed += WideCharToMultiByte(CP_ACP, 0,
1232 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1233 NULL, 0, NULL, NULL);
1234 if(lpOTMW->otmpFaceName)
1235 needed += WideCharToMultiByte(CP_ACP, 0,
1236 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1237 NULL, 0, NULL, NULL);
1238 if(lpOTMW->otmpStyleName)
1239 needed += WideCharToMultiByte(CP_ACP, 0,
1240 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1241 NULL, 0, NULL, NULL);
1242 if(lpOTMW->otmpFullName)
1243 needed += WideCharToMultiByte(CP_ACP, 0,
1244 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1245 NULL, 0, NULL, NULL);
1247 if(!lpOTM) {
1248 ret = needed;
1249 goto end;
1252 if(needed > cbData) {
1253 ret = 0;
1254 goto end;
1258 lpOTM->otmSize = needed;
1259 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1260 lpOTM->otmFiller = 0;
1261 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1262 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1263 lpOTM->otmfsType = lpOTMW->otmfsType;
1264 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1265 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1266 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1267 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1268 lpOTM->otmAscent = lpOTMW->otmAscent;
1269 lpOTM->otmDescent = lpOTMW->otmDescent;
1270 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1271 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1272 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1273 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1274 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1275 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1276 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1277 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1278 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1279 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1280 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1281 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1282 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1283 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1284 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1285 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1288 ptr = (char*)(lpOTM + 1);
1289 left = needed - sizeof(*lpOTM);
1291 if(lpOTMW->otmpFamilyName) {
1292 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1293 len = WideCharToMultiByte(CP_ACP, 0,
1294 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1295 ptr, left, NULL, NULL);
1296 left -= len;
1297 ptr += len;
1298 } else
1299 lpOTM->otmpFamilyName = 0;
1301 if(lpOTMW->otmpFaceName) {
1302 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1303 len = WideCharToMultiByte(CP_ACP, 0,
1304 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1305 ptr, left, NULL, NULL);
1306 left -= len;
1307 ptr += len;
1308 } else
1309 lpOTM->otmpFaceName = 0;
1311 if(lpOTMW->otmpStyleName) {
1312 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1313 len = WideCharToMultiByte(CP_ACP, 0,
1314 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1315 ptr, left, NULL, NULL);
1316 left -= len;
1317 ptr += len;
1318 } else
1319 lpOTM->otmpStyleName = 0;
1321 if(lpOTMW->otmpFullName) {
1322 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1323 len = WideCharToMultiByte(CP_ACP, 0,
1324 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1325 ptr, left, NULL, NULL);
1326 left -= len;
1327 } else
1328 lpOTM->otmpFullName = 0;
1330 assert(left == 0);
1332 ret = needed;
1334 end:
1335 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1336 HeapFree(GetProcessHeap(), 0, lpOTMW);
1338 return ret;
1342 /***********************************************************************
1343 * GetOutlineTextMetricsW [GDI32.@]
1345 UINT WINAPI GetOutlineTextMetricsW(
1346 HDC hdc, /* [in] Handle of device context */
1347 UINT cbData, /* [in] Size of metric data array */
1348 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1350 DC *dc = DC_GetDCPtr( hdc );
1351 UINT ret;
1353 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1354 if(!dc) return 0;
1356 if(dc->gdiFont) {
1357 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1358 if(ret && ret <= cbData) {
1359 #define WDPTOLP(x) ((x<0)? \
1360 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1361 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1362 #define HDPTOLP(y) ((y<0)? \
1363 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1364 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1366 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1367 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1368 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1369 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1370 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1371 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1372 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1373 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1374 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1375 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1376 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1377 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1378 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1379 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1380 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1381 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1382 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1383 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1384 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1385 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1386 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1387 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1388 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1389 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1390 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1391 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1392 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1393 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1394 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1395 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1396 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1397 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1398 #undef WDPTOLP
1399 #undef HDPTOLP
1403 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1404 but really this should just be a return 0. */
1406 ret = sizeof(*lpOTM);
1407 if (lpOTM) {
1408 if(cbData < ret)
1409 ret = 0;
1410 else {
1411 memset(lpOTM, 0, ret);
1412 lpOTM->otmSize = sizeof(*lpOTM);
1413 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1415 Further fill of the structure not implemented,
1416 Needs real values for the structure members
1421 GDI_ReleaseObj(hdc);
1422 return ret;
1426 /***********************************************************************
1427 * GetCharWidthW (GDI32.@)
1428 * GetCharWidth32W (GDI32.@)
1430 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1431 LPINT buffer )
1433 UINT i, extra;
1434 BOOL ret = FALSE;
1435 DC * dc = DC_GetDCPtr( hdc );
1436 if (!dc) return FALSE;
1438 if (dc->gdiFont)
1439 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1440 else if (dc->funcs->pGetCharWidth)
1441 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1443 if (ret)
1445 /* convert device units to logical */
1447 extra = dc->vportExtX >> 1;
1448 for( i = firstChar; i <= lastChar; i++, buffer++ )
1449 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1450 ret = TRUE;
1452 GDI_ReleaseObj( hdc );
1453 return ret;
1457 /***********************************************************************
1458 * GetCharWidthA (GDI32.@)
1459 * GetCharWidth32A (GDI32.@)
1461 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1462 LPINT buffer )
1464 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1465 LPSTR str;
1466 LPWSTR wstr;
1467 BOOL ret = TRUE;
1469 if(count <= 0) return FALSE;
1471 str = HeapAlloc(GetProcessHeap(), 0, count);
1472 for(i = 0; i < count; i++)
1473 str[i] = (BYTE)(firstChar + i);
1475 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1477 for(i = 0; i < wlen; i++)
1479 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1481 ret = FALSE;
1482 break;
1484 buffer++;
1487 HeapFree(GetProcessHeap(), 0, str);
1488 HeapFree(GetProcessHeap(), 0, wstr);
1490 return ret;
1494 /* FIXME: all following APIs ******************************************/
1497 /***********************************************************************
1498 * SetMapperFlags (GDI32.@)
1500 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1502 DC *dc = DC_GetDCPtr( hDC );
1503 DWORD ret = 0;
1504 if(!dc) return 0;
1505 if(dc->funcs->pSetMapperFlags)
1506 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1507 else
1508 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1509 GDI_ReleaseObj( hDC );
1510 return ret;
1513 /***********************************************************************
1514 * GetAspectRatioFilterEx (GDI.486)
1516 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1518 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1519 return FALSE;
1522 /***********************************************************************
1523 * GetAspectRatioFilterEx (GDI32.@)
1525 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1527 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1528 return FALSE;
1532 /***********************************************************************
1533 * GetCharABCWidthsA (GDI32.@)
1535 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1536 LPABC abc )
1538 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1539 LPSTR str;
1540 LPWSTR wstr;
1541 BOOL ret = TRUE;
1543 if(count <= 0) return FALSE;
1545 str = HeapAlloc(GetProcessHeap(), 0, count);
1546 for(i = 0; i < count; i++)
1547 str[i] = (BYTE)(firstChar + i);
1549 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1551 for(i = 0; i < wlen; i++)
1553 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1555 ret = FALSE;
1556 break;
1558 abc++;
1561 HeapFree(GetProcessHeap(), 0, str);
1562 HeapFree(GetProcessHeap(), 0, wstr);
1564 return ret;
1568 /******************************************************************************
1569 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1571 * PARAMS
1572 * hdc [I] Handle of device context
1573 * firstChar [I] First character in range to query
1574 * lastChar [I] Last character in range to query
1575 * abc [O] Address of character-width structure
1577 * NOTES
1578 * Only works with TrueType fonts
1580 * RETURNS
1581 * Success: TRUE
1582 * Failure: FALSE
1584 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1585 LPABC abc )
1587 DC *dc = DC_GetDCPtr(hdc);
1588 int i;
1589 GLYPHMETRICS gm;
1590 BOOL ret = FALSE;
1592 if(dc->gdiFont) {
1593 for (i=firstChar;i<=lastChar;i++) {
1594 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1595 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1596 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1597 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1599 ret = TRUE;
1601 GDI_ReleaseObj(hdc);
1602 return ret;
1606 /***********************************************************************
1607 * GetGlyphOutline (GDI.309)
1609 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1610 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1611 LPVOID lpBuffer, const MAT2 *lpmat2 )
1613 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1614 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1615 return (DWORD)-1; /* failure */
1619 /***********************************************************************
1620 * GetGlyphOutlineA (GDI32.@)
1622 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1623 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1624 LPVOID lpBuffer, const MAT2 *lpmat2 )
1626 LPWSTR p = NULL;
1627 DWORD ret;
1628 UINT c;
1630 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1631 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1632 c = p[0];
1633 } else
1634 c = uChar;
1635 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1636 lpmat2);
1637 if(p)
1638 HeapFree(GetProcessHeap(), 0, p);
1639 return ret;
1642 /***********************************************************************
1643 * GetGlyphOutlineW (GDI32.@)
1645 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1646 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1647 LPVOID lpBuffer, const MAT2 *lpmat2 )
1649 DC *dc = DC_GetDCPtr(hdc);
1650 DWORD ret;
1652 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1653 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1655 if(!dc) return GDI_ERROR;
1657 if(dc->gdiFont)
1658 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1659 cbBuffer, lpBuffer, lpmat2);
1660 else
1661 ret = GDI_ERROR;
1663 GDI_ReleaseObj(hdc);
1664 return ret;
1668 /***********************************************************************
1669 * CreateScalableFontResourceA (GDI32.@)
1671 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1672 LPCSTR lpszResourceFile,
1673 LPCSTR lpszFontFile,
1674 LPCSTR lpszCurrentPath )
1676 HANDLE f;
1678 /* fHidden=1 - only visible for the calling app, read-only, not
1679 * enumbered with EnumFonts/EnumFontFamilies
1680 * lpszCurrentPath can be NULL
1682 FIXME("(%ld,%s,%s,%s): stub\n",
1683 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1684 debugstr_a(lpszCurrentPath) );
1686 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1687 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1688 CloseHandle(f);
1689 SetLastError(ERROR_FILE_EXISTS);
1690 return FALSE;
1692 return FALSE; /* create failed */
1695 /***********************************************************************
1696 * CreateScalableFontResourceW (GDI32.@)
1698 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1699 LPCWSTR lpszResourceFile,
1700 LPCWSTR lpszFontFile,
1701 LPCWSTR lpszCurrentPath )
1703 FIXME("(%ld,%p,%p,%p): stub\n",
1704 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1705 return FALSE; /* create failed */
1709 /*************************************************************************
1710 * GetRasterizerCaps (GDI32.@)
1712 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1714 lprs->nSize = sizeof(RASTERIZER_STATUS);
1715 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1716 lprs->nLanguageID = 0;
1717 return TRUE;
1721 /*************************************************************************
1722 * GetKerningPairsA (GDI32.@)
1724 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs, LPKERNINGPAIR lpKerningPairs )
1726 int i;
1727 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1728 for (i = 0; i < cPairs; i++)
1729 lpKerningPairs[i].iKernAmount = 0;
1730 return 0;
1734 /*************************************************************************
1735 * GetKerningPairsW (GDI32.@)
1737 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1738 LPKERNINGPAIR lpKerningPairs )
1740 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1743 /*************************************************************************
1744 * TranslateCharsetInfo [GDI32.@]
1746 * Fills a CHARSETINFO structure for a character set, code page, or
1747 * font. This allows making the correspondance between different labelings
1748 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1749 * of the same encoding.
1751 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1752 * only one codepage should be set in *lpSrc.
1754 * RETURNS
1755 * TRUE on success, FALSE on failure.
1758 BOOL WINAPI TranslateCharsetInfo(
1759 LPDWORD lpSrc, /* [in]
1760 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1761 if flags == TCI_SRCCHARSET: a character set value
1762 if flags == TCI_SRCCODEPAGE: a code page value
1764 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1765 DWORD flags /* [in] determines interpretation of lpSrc */
1767 int index = 0;
1768 switch (flags) {
1769 case TCI_SRCFONTSIG:
1770 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1771 break;
1772 case TCI_SRCCODEPAGE:
1773 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1774 break;
1775 case TCI_SRCCHARSET:
1776 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1777 break;
1778 default:
1779 return FALSE;
1781 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1782 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1783 return TRUE;
1786 /*************************************************************************
1787 * GetFontLanguageInfo (GDI32.@)
1789 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1791 FONTSIGNATURE fontsig;
1792 static const DWORD GCP_DBCS_MASK=0x003F0000,
1793 GCP_DIACRITIC_MASK=0x00000000,
1794 FLI_GLYPHS_MASK=0x00000000,
1795 GCP_GLYPHSHAPE_MASK=0x00000040,
1796 GCP_KASHIDA_MASK=0x00000000,
1797 GCP_LIGATE_MASK=0x00000000,
1798 GCP_USEKERNING_MASK=0x00000000,
1799 GCP_REORDER_MASK=0x00000060;
1801 DWORD result=0;
1803 GetTextCharsetInfo( hdc, &fontsig, 0 );
1804 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1806 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1807 result|=GCP_DBCS;
1809 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1810 result|=GCP_DIACRITIC;
1812 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1813 result|=FLI_GLYPHS;
1815 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1816 result|=GCP_GLYPHSHAPE;
1818 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1819 result|=GCP_KASHIDA;
1821 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1822 result|=GCP_LIGATE;
1824 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1825 result|=GCP_USEKERNING;
1827 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1828 result|=GCP_REORDER;
1830 return result;
1834 /*************************************************************************
1835 * GetFontData [GDI32.@] Retrieve data for TrueType font
1837 * RETURNS
1839 * success: Number of bytes returned
1840 * failure: GDI_ERROR
1842 * NOTES
1844 * Calls SetLastError()
1847 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1848 LPVOID buffer, DWORD length)
1850 DC *dc = DC_GetDCPtr(hdc);
1851 DWORD ret = GDI_ERROR;
1853 if(!dc) return GDI_ERROR;
1855 if(dc->gdiFont)
1856 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1858 GDI_ReleaseObj(hdc);
1859 return ret;
1862 /*************************************************************************
1863 * GetGlyphIndicesA [GDI32.@]
1865 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1866 LPWORD pgi, DWORD flags)
1868 DWORD ret;
1869 WCHAR *lpstrW;
1870 INT countW;
1872 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1873 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1875 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1876 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1877 HeapFree(GetProcessHeap(), 0, lpstrW);
1879 return ret;
1882 /*************************************************************************
1883 * GetGlyphIndicesW [GDI32.@]
1885 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1886 LPWORD pgi, DWORD flags)
1888 DC *dc = DC_GetDCPtr(hdc);
1889 DWORD ret = GDI_ERROR;
1891 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1892 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1894 if(!dc) return GDI_ERROR;
1896 if(dc->gdiFont)
1897 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1899 GDI_ReleaseObj(hdc);
1900 return ret;
1903 /*************************************************************************
1904 * GetCharacterPlacementA [GDI32.@]
1906 * NOTES:
1907 * the web browser control of ie4 calls this with dwFlags=0
1909 DWORD WINAPI
1910 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1911 INT nMaxExtent, GCP_RESULTSA *lpResults,
1912 DWORD dwFlags)
1914 WCHAR *lpStringW;
1915 INT uCountW, i;
1916 GCP_RESULTSW resultsW;
1917 DWORD ret;
1918 UINT font_cp;
1920 TRACE("%s, %d, %d, 0x%08lx\n",
1921 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1923 /* both structs are equal in size */
1924 memcpy(&resultsW, lpResults, sizeof(resultsW));
1926 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1927 if(lpResults->lpOutString)
1928 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1930 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1932 if(lpResults->lpOutString) {
1933 if(font_cp != CP_SYMBOL)
1934 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1935 lpResults->lpOutString, uCount, NULL, NULL );
1936 else
1937 for(i = 0; i < uCount; i++)
1938 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1941 HeapFree(GetProcessHeap(), 0, lpStringW);
1942 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1944 return ret;
1947 /*************************************************************************
1948 * GetCharacterPlacementW [GDI32.@]
1950 * Retrieve information about a string. This includes the width, reordering,
1951 * Glyphing and so on.
1953 * RETURNS
1955 * The width and height of the string if succesful, 0 if failed.
1957 * BUGS
1959 * All flags except GCP_REORDER are not yet implemented.
1960 * Reordering is not 100% complient to the Windows BiDi method.
1961 * Caret positioning is not yet implemented.
1962 * Classes are not yet implemented.
1965 DWORD WINAPI
1966 GetCharacterPlacementW(
1967 HDC hdc, /* [in] Device context for which the rendering is to be done */
1968 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1969 INT uCount, /* [in] Number of WORDS in string. */
1970 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1971 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1972 DWORD dwFlags /* [in] Flags specifying how to process the string */
1975 DWORD ret=0;
1976 SIZE size;
1977 UINT i, nSet;
1979 TRACE("%s, %d, %d, 0x%08lx\n",
1980 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1982 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1983 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1984 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1985 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1986 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1988 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1989 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1990 if(lpResults->lpClass) FIXME("classes not implemented\n");
1992 nSet = (UINT)uCount;
1993 if(nSet > lpResults->nGlyphs)
1994 nSet = lpResults->nGlyphs;
1996 /* return number of initialized fields */
1997 lpResults->nGlyphs = nSet;
1999 if(dwFlags==0)
2001 /* Treat the case where no special handling was requested in a fastpath way */
2002 /* copy will do if the GCP_REORDER flag is not set */
2003 if(lpResults->lpOutString)
2004 for(i=0; i<nSet && lpString[i]!=0; ++i )
2005 lpResults->lpOutString[i]=lpString[i];
2007 if(lpResults->lpOrder)
2009 for(i = 0; i < nSet; i++)
2010 lpResults->lpOrder[i] = i;
2014 if((dwFlags&GCP_REORDER)!=0)
2016 WORD *pwCharType;
2017 int run_end;
2018 /* Keep a static table that translates the C2 types to something meaningful */
2019 /* 1 - left to right
2020 * -1 - right to left
2021 * 0 - neutral
2023 static const int chardir[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
2025 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
2026 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
2028 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2030 return 0;
2033 /* Fill in the order array with directionality values */
2034 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2036 /* The complete and correct (at least according to MS) BiDi algorythm is not
2037 * yet implemented here. Instead, we just make sure that consecutive runs of
2038 * the same direction (or neutral) are ordered correctly. We also assign Neutrals
2039 * that are between runs of opposing directions the base (ok, always LTR) dir.
2040 * While this is a LONG way from a BiDi algorithm, it does produce more or less
2041 * readable results.
2043 for( i=0; i<uCount; i+=run_end )
2045 for( run_end=1; i+run_end<uCount &&
2046 (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2047 chardir[pwCharType[i+run_end]]==0); ++run_end )
2050 if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2052 /* A LTR run */
2053 if(lpResults->lpOutString)
2055 int j;
2056 for( j=0; j<run_end; j++ )
2058 lpResults->lpOutString[i+j]=lpString[i+j];
2062 if(lpResults->lpOrder)
2064 int j;
2065 for( j=0; j<run_end; j++ )
2066 lpResults->lpOrder[i+j] = i+j;
2068 } else
2070 /* A RTL run */
2072 /* Since, at this stage, the paragraph context is always LTR,
2073 * remove any neutrals from the end of this run.
2075 if( chardir[pwCharType[i]]!=0 )
2076 while( chardir[pwCharType[i+run_end-1]]==0 )
2077 --run_end;
2079 if(lpResults->lpOutString)
2081 int j;
2082 for( j=0; j<run_end; j++ )
2084 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2088 if(lpResults->lpOrder)
2090 int j;
2091 for( j=0; j<run_end; j++ )
2092 lpResults->lpOrder[i+j] = i+run_end-j-1;
2097 HeapFree(GetProcessHeap(), 0, pwCharType);
2100 /* FIXME: Will use the placement chars */
2101 if (lpResults->lpDx)
2103 int c;
2104 for (i = 0; i < nSet; i++)
2106 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2107 lpResults->lpDx[i]= c;
2111 if(lpResults->lpGlyphs)
2112 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2114 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2115 ret = MAKELONG(size.cx, size.cy);
2117 return ret;
2120 /*************************************************************************
2121 * GetCharABCWidthsFloatA [GDI32.@]
2123 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2124 LPABCFLOAT lpABCF)
2126 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2127 return 0;
2130 /*************************************************************************
2131 * GetCharABCWidthsFloatW [GDI32.@]
2133 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2134 UINT iLastChar, LPABCFLOAT lpABCF)
2136 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2137 return 0;
2140 /*************************************************************************
2141 * GetCharWidthFloatA [GDI32.@]
2143 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2144 UINT iLastChar, PFLOAT pxBuffer)
2146 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2147 return 0;
2150 /*************************************************************************
2151 * GetCharWidthFloatW [GDI32.@]
2153 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2154 UINT iLastChar, PFLOAT pxBuffer)
2156 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2157 return 0;
2161 /***********************************************************************
2163 * Font Resource API *
2165 ***********************************************************************/
2167 /***********************************************************************
2168 * AddFontResourceA (GDI32.@)
2170 INT WINAPI AddFontResourceA( LPCSTR str )
2172 return AddFontResourceExA( str, 0, NULL);
2175 /***********************************************************************
2176 * AddFontResourceW (GDI32.@)
2178 INT WINAPI AddFontResourceW( LPCWSTR str )
2180 return AddFontResourceExW(str, 0, NULL);
2184 /***********************************************************************
2185 * AddFontResourceExA (GDI32.@)
2187 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2189 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2190 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2191 INT ret;
2193 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2194 ret = AddFontResourceExW(strW, fl, pdv);
2195 HeapFree(GetProcessHeap(), 0, strW);
2196 return ret;
2199 /***********************************************************************
2200 * AddFontResourceExW (GDI32.@)
2202 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2204 return WineEngAddFontResourceEx(str, fl, pdv);
2207 /***********************************************************************
2208 * RemoveFontResourceA (GDI32.@)
2210 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2212 return RemoveFontResourceExA(str, 0, 0);
2215 /***********************************************************************
2216 * RemoveFontResourceW (GDI32.@)
2218 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2220 return RemoveFontResourceExW(str, 0, 0);
2223 /***********************************************************************
2224 * RemoveFontResourceExA (GDI32.@)
2226 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2228 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2229 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2230 INT ret;
2232 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2233 ret = RemoveFontResourceExW(strW, fl, pdv);
2234 HeapFree(GetProcessHeap(), 0, strW);
2235 return ret;
2238 /***********************************************************************
2239 * RemoveFontResourceExW (GDI32.@)
2241 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2243 return WineEngRemoveFontResourceEx(str, fl, pdv);