4 * Copyright 1993 Alexandre Julliard
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
23 #include "wine/port.h"
30 #include "wine/unicode.h"
32 #include "wine/debug.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
65 LPLOGFONT16 lpLogFontParam
;
66 FONTENUMPROCEX16 lpEnumFunc
;
69 LPNEWTEXTMETRICEX16 lpTextMetric
;
70 LPENUMLOGFONTEX16 lpLogFont
;
80 LPLOGFONTW lpLogFontParam
;
81 FONTENUMPROCEXW lpEnumFunc
;
90 * For TranslateCharsetInfo
92 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
93 #define MAXTCIINDEX 32
94 static CHARSETINFO FONT_tci
[MAXTCIINDEX
] = {
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)},
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
,
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
)
299 FONT_LogFontAToW( plfA
, &lfW
);
300 return CreateFontIndirectW( &lfW
);
302 return CreateFontIndirectW( NULL
);
306 /***********************************************************************
307 * CreateFontIndirectW (GDI32.@)
309 HFONT WINAPI
CreateFontIndirectW( const LOGFONTW
*plf
)
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");
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
,
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
;
369 lstrcpynA(logfont
.lfFaceName
,name
,sizeof(logfont
.lfFaceName
));
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
)
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
;
402 lstrcpynA(logfont
.lfFaceName
,name
,sizeof(logfont
.lfFaceName
));
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
)
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
;
435 lstrcpynW(logfont
.lfFaceName
, name
,
436 sizeof(logfont
.lfFaceName
) / sizeof(WCHAR
));
438 logfont
.lfFaceName
[0] = '\0';
440 return CreateFontIndirectW( &logfont
);
444 /***********************************************************************
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
455 static HGDIOBJ
FONT_SelectObject( HGDIOBJ handle
, void *obj
, HDC hdc
)
458 DC
*dc
= DC_GetDCPtr( hdc
);
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 */
479 GDI_ReleaseObj( hdc
);
484 /***********************************************************************
487 static INT
FONT_GetObject16( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
492 FONT_LogFontWTo16( &font
->logfont
, &lf16
);
494 if (count
> sizeof(LOGFONT16
)) count
= sizeof(LOGFONT16
);
495 memcpy( buffer
, &lf16
, count
);
499 /***********************************************************************
502 static INT
FONT_GetObjectA( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
507 FONT_LogFontWToA( &font
->logfont
, &lfA
);
509 if (count
> sizeof(lfA
)) count
= sizeof(lfA
);
511 memcpy( buffer
, &lfA
, count
);
515 /***********************************************************************
518 static INT
FONT_GetObjectW( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
521 if (count
> sizeof(LOGFONTW
)) count
= sizeof(LOGFONTW
);
523 memcpy( buffer
, &font
->logfont
, count
);
528 /***********************************************************************
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
;
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 */
572 /***********************************************************************
575 static INT
FONT_EnumInstance( LPENUMLOGFONTEXW plf
, LPNEWTEXTMETRICEXW ptm
,
576 DWORD fType
, LPARAM lp
)
578 fontEnum32
*pfe
= (fontEnum32
*)lp
;
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 */
614 /***********************************************************************
615 * EnumFontFamiliesEx (GDI.613)
617 INT16 WINAPI
EnumFontFamiliesEx16( HDC16 hDC
, LPLOGFONT16 plf
,
618 FONTENUMPROCEX16 efproc
, LPARAM lParam
,
623 DC
* dc
= DC_GetDCPtr( hDC
);
628 fe16
.physDev
= dc
->physDev
;
630 if (dc
->funcs
->pEnumDeviceFonts
)
632 NEWTEXTMETRICEX16 tm16
;
633 ENUMLOGFONTEX16 lf16
;
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
);
654 /***********************************************************************
655 * FONT_EnumFontFamiliesEx
657 static INT
FONT_EnumFontFamiliesEx( HDC hDC
, LPLOGFONTW plf
,
658 FONTENUMPROCEXW efproc
,
659 LPARAM lParam
, DWORD dwUnicode
)
662 DC
*dc
= DC_GetDCPtr( hDC
);
668 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf
->lfFaceName
),
670 fe32
.lpLogFontParam
= plf
;
671 fe32
.lpEnumFunc
= efproc
;
672 fe32
.lpData
= lParam
;
673 fe32
.dwFlags
= dwUnicode
;
676 fe32
.physDev
= dc
->physDev
;
678 enum_gdi_fonts
= GetDeviceCaps(hDC
, TEXTCAPS
) & TC_VA_ABLE
;
680 if (!dc
->funcs
->pEnumDeviceFonts
&& !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 */
695 if (fe32
.hdc
) GDI_ReleaseObj( fe32
.hdc
);
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
)
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
)
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
)
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
)
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 /***********************************************************************
771 INT16 WINAPI
EnumFonts16( HDC16 hDC
, LPCSTR lpName
, FONTENUMPROC16 efproc
,
774 return EnumFontFamilies16( hDC
, lpName
, (FONTENUMPROCEX16
)efproc
, lpData
);
777 /***********************************************************************
778 * EnumFontsA (GDI32.@)
780 INT WINAPI
EnumFontsA( HDC hDC
, LPCSTR lpName
, FONTENUMPROCA efproc
,
783 return EnumFontFamiliesA( hDC
, lpName
, efproc
, lpData
);
786 /***********************************************************************
787 * EnumFontsW (GDI32.@)
789 INT WINAPI
EnumFontsW( HDC hDC
, LPCWSTR lpName
, FONTENUMPROCW efproc
,
792 return EnumFontFamiliesW( hDC
, lpName
, efproc
, lpData
);
796 /***********************************************************************
797 * GetTextCharacterExtra (GDI32.@)
799 INT WINAPI
GetTextCharacterExtra( HDC hdc
)
802 DC
*dc
= DC_GetDCPtr( hdc
);
804 ret
= abs( (dc
->charExtra
* dc
->wndExtX
+ dc
->vportExtX
/ 2)
806 GDI_ReleaseObj( hdc
);
811 /***********************************************************************
812 * SetTextCharacterExtra (GDI32.@)
814 INT WINAPI
SetTextCharacterExtra( HDC hdc
, INT extra
)
817 DC
* dc
= DC_GetDCPtr( hdc
);
819 if (dc
->funcs
->pSetTextCharacterExtra
)
820 prev
= dc
->funcs
->pSetTextCharacterExtra( dc
->physDev
, extra
);
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
);
832 /***********************************************************************
833 * SetTextJustification (GDI32.@)
835 BOOL WINAPI
SetTextJustification( HDC hdc
, INT extra
, INT breaks
)
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
);
844 extra
= abs((extra
* dc
->vportExtX
+ dc
->wndExtX
/ 2) / dc
->wndExtX
);
845 if (!extra
) breaks
= 0;
846 dc
->breakTotalExtra
= extra
;
847 dc
->breakCount
= breaks
;
850 dc
->breakExtra
= extra
/ breaks
;
851 dc
->breakRem
= extra
- (dc
->breakCount
* dc
->breakExtra
);
859 GDI_ReleaseObj( hdc
);
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
);
874 res
= WideCharToMultiByte( CP_ACP
, 0, nameW
, -1, name
, count
,
877 res
= WideCharToMultiByte( CP_ACP
, 0, nameW
, -1, NULL
, 0, NULL
, NULL
);
878 HeapFree( GetProcessHeap(), 0, nameW
);
882 /***********************************************************************
883 * GetTextFaceW (GDI32.@)
885 INT WINAPI
GetTextFaceW( HDC hdc
, INT count
, LPWSTR name
)
890 DC
* dc
= DC_GetDCPtr( hdc
);
894 ret
= WineEngGetTextFace(dc
->gdiFont
, count
, name
);
895 else if ((font
= (FONTOBJ
*) GDI_GetObjPtr( dc
->hFont
, FONT_MAGIC
)))
899 lstrcpynW( name
, font
->logfont
.lfFaceName
, count
);
902 else ret
= strlenW(font
->logfont
.lfFaceName
) + 1;
903 GDI_ReleaseObj( dc
->hFont
);
905 GDI_ReleaseObj( hdc
);
910 /***********************************************************************
911 * GetTextExtentPoint32A (GDI32.@)
913 BOOL WINAPI
GetTextExtentPoint32A( HDC hdc
, LPCSTR str
, INT count
,
918 LPWSTR p
= FONT_mbtowc(hdc
, str
, count
, &wlen
, NULL
);
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
);
931 /***********************************************************************
932 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
934 * Computes width and height of the specified string.
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 */
947 DC
* dc
= DC_GetDCPtr( hdc
);
948 if (!dc
) return FALSE
;
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
);
965 /***********************************************************************
966 * GetTextExtentPointI [GDI32.@]
968 * Computes width and height of the array of glyph indices.
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 */
981 DC
* dc
= DC_GetDCPtr( hdc
);
982 if (!dc
) return FALSE
;
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
);
1002 /***********************************************************************
1003 * GetTextExtentPointA (GDI32.@)
1005 BOOL WINAPI
GetTextExtentPointA( HDC hdc
, LPCSTR str
, INT count
,
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
,
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
)
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
);
1039 /***********************************************************************
1040 * GetTextExtentExPointW (GDI32.@)
1042 * Return the size of the string as it would be if it was output properly by
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.
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
;
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.
1089 if( !lpnFit
|| extent
<= maxExt
)
1090 /* It is allowed to be equal. */
1093 if( alpDx
) alpDx
[index
] = extent
;
1095 if( tSize
.cy
> size
->cy
) size
->cy
= tSize
.cy
;
1099 if(lpnFit
) *lpnFit
= nFit
;
1102 TRACE("returning %d %ld x %ld\n",nFit
,size
->cx
,size
->cy
);
1108 /***********************************************************************
1109 * GetTextMetricsA (GDI32.@)
1111 BOOL WINAPI
GetTextMetricsA( HDC hdc
, TEXTMETRICA
*metrics
)
1115 if (!GetTextMetricsW( hdc
, &tm32
)) return FALSE
;
1116 FONT_TextMetricWToA( &tm32
, metrics
);
1120 /***********************************************************************
1121 * GetTextMetricsW (GDI32.@)
1123 BOOL WINAPI
GetTextMetricsW( HDC hdc
, TEXTMETRICW
*metrics
)
1126 DC
* dc
= DC_GetDCPtr( hdc
);
1127 if (!dc
) return FALSE
;
1130 ret
= WineEngGetTextMetrics(dc
->gdiFont
, metrics
);
1131 else if (dc
->funcs
->pGetTextMetrics
)
1132 ret
= dc
->funcs
->pGetTextMetrics( dc
->physDev
, metrics
);
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
);
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"
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
,
1176 metrics
->tmHeight
);
1178 GDI_ReleaseObj( hdc
);
1183 /***********************************************************************
1184 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1187 * lpOTM should be LPOUTLINETEXTMETRIC
1190 * Success: Non-zero or size of required buffer
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
);
1203 /***********************************************************************
1204 * GetOutlineTextMetricsA (GDI32.@)
1205 * Gets metrics for TrueType fonts.
1209 * Success: Non-zero or size of required buffer
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
;
1219 OUTLINETEXTMETRICW
*lpOTMW
= (OUTLINETEXTMETRICW
*)buf
;
1222 if((ret
= GetOutlineTextMetricsW(hdc
, sizeof(buf
), lpOTMW
)) == 0) {
1223 if((ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
)) == 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
);
1252 if(needed
> cbData
) {
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
);
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
);
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
);
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
);
1328 lpOTM
->otmpFullName
= 0;
1335 if(lpOTMW
!= (OUTLINETEXTMETRICW
*)buf
)
1336 HeapFree(GetProcessHeap(), 0, lpOTMW
);
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
);
1353 TRACE("(%d,%d,%p)\n", hdc
, cbData
, lpOTM
);
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
);
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
);
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
);
1426 /***********************************************************************
1427 * GetCharWidthW (GDI32.@)
1428 * GetCharWidth32W (GDI32.@)
1430 BOOL WINAPI
GetCharWidth32W( HDC hdc
, UINT firstChar
, UINT lastChar
,
1435 DC
* dc
= DC_GetDCPtr( hdc
);
1436 if (!dc
) return FALSE
;
1439 ret
= WineEngGetCharWidth( dc
->gdiFont
, firstChar
, lastChar
, buffer
);
1440 else if (dc
->funcs
->pGetCharWidth
)
1441 ret
= dc
->funcs
->pGetCharWidth( dc
->physDev
, firstChar
, lastChar
, buffer
);
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
;
1452 GDI_ReleaseObj( hdc
);
1457 /***********************************************************************
1458 * GetCharWidthA (GDI32.@)
1459 * GetCharWidth32A (GDI32.@)
1461 BOOL WINAPI
GetCharWidth32A( HDC hdc
, UINT firstChar
, UINT lastChar
,
1464 INT i
, wlen
, count
= (INT
)(lastChar
- firstChar
+ 1);
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
))
1487 HeapFree(GetProcessHeap(), 0, str
);
1488 HeapFree(GetProcessHeap(), 0, wstr
);
1494 /* FIXME: all following APIs ******************************************/
1497 /***********************************************************************
1498 * SetMapperFlags (GDI32.@)
1500 DWORD WINAPI
SetMapperFlags( HDC hDC
, DWORD dwFlag
)
1502 DC
*dc
= DC_GetDCPtr( hDC
);
1505 if(dc
->funcs
->pSetMapperFlags
)
1506 ret
= dc
->funcs
->pSetMapperFlags( dc
->physDev
, dwFlag
);
1508 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC
, dwFlag
);
1509 GDI_ReleaseObj( hDC
);
1513 /***********************************************************************
1514 * GetAspectRatioFilterEx (GDI.486)
1516 BOOL16 WINAPI
GetAspectRatioFilterEx16( HDC16 hdc
, LPSIZE16 pAspectRatio
)
1518 FIXME("(%04x, %p): -- Empty Stub !\n", hdc
, pAspectRatio
);
1522 /***********************************************************************
1523 * GetAspectRatioFilterEx (GDI32.@)
1525 BOOL WINAPI
GetAspectRatioFilterEx( HDC hdc
, LPSIZE pAspectRatio
)
1527 FIXME("(%04x, %p): -- Empty Stub !\n", hdc
, pAspectRatio
);
1532 /***********************************************************************
1533 * GetCharABCWidthsA (GDI32.@)
1535 BOOL WINAPI
GetCharABCWidthsA(HDC hdc
, UINT firstChar
, UINT lastChar
,
1538 INT i
, wlen
, count
= (INT
)(lastChar
- firstChar
+ 1);
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
))
1561 HeapFree(GetProcessHeap(), 0, str
);
1562 HeapFree(GetProcessHeap(), 0, wstr
);
1568 /******************************************************************************
1569 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
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
1578 * Only works with TrueType fonts
1584 BOOL WINAPI
GetCharABCWidthsW( HDC hdc
, UINT firstChar
, UINT lastChar
,
1587 DC
*dc
= DC_GetDCPtr(hdc
);
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
;
1601 GDI_ReleaseObj(hdc
);
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
)
1630 if(!(fuFormat
& GGO_GLYPH_INDEX
)) {
1631 p
= FONT_mbtowc(hdc
, (char*)&uChar
, 1, NULL
, NULL
);
1635 ret
= GetGlyphOutlineW(hdc
, c
, fuFormat
, lpgm
, cbBuffer
, lpBuffer
,
1638 HeapFree(GetProcessHeap(), 0, p
);
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
);
1652 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1653 hdc
, uChar
, fuFormat
, lpgm
, cbBuffer
, lpBuffer
, lpmat2
);
1655 if(!dc
) return GDI_ERROR
;
1658 ret
= WineEngGetGlyphOutline(dc
->gdiFont
, uChar
, fuFormat
, lpgm
,
1659 cbBuffer
, lpBuffer
, lpmat2
);
1663 GDI_ReleaseObj(hdc
);
1668 /***********************************************************************
1669 * CreateScalableFontResourceA (GDI32.@)
1671 BOOL WINAPI
CreateScalableFontResourceA( DWORD fHidden
,
1672 LPCSTR lpszResourceFile
,
1673 LPCSTR lpszFontFile
,
1674 LPCSTR lpszCurrentPath
)
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
) {
1689 SetLastError(ERROR_FILE_EXISTS
);
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;
1721 /*************************************************************************
1722 * GetKerningPairsA (GDI32.@)
1724 DWORD WINAPI
GetKerningPairsA( HDC hDC
, DWORD cPairs
, LPKERNINGPAIR lpKerningPairs
)
1727 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC
, cPairs
, lpKerningPairs
);
1728 for (i
= 0; i
< cPairs
; i
++)
1729 lpKerningPairs
[i
].iKernAmount
= 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.
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 */
1769 case TCI_SRCFONTSIG
:
1770 while (!(*lpSrc
>>index
& 0x0001) && index
<MAXTCIINDEX
) index
++;
1772 case TCI_SRCCODEPAGE
:
1773 while ((UINT
) (lpSrc
) != FONT_tci
[index
].ciACP
&& index
< MAXTCIINDEX
) index
++;
1775 case TCI_SRCCHARSET
:
1776 while ((UINT
) (lpSrc
) != FONT_tci
[index
].ciCharset
&& index
< MAXTCIINDEX
) index
++;
1781 if (index
>= MAXTCIINDEX
|| FONT_tci
[index
].ciCharset
== DEFAULT_CHARSET
) return FALSE
;
1782 memcpy(lpCs
, &FONT_tci
[index
], sizeof(CHARSETINFO
));
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;
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 )
1809 if( (fontsig
.fsCsb
[0]&GCP_DIACRITIC_MASK
)!=0 )
1810 result
|=GCP_DIACRITIC
;
1812 if( (fontsig
.fsCsb
[0]&FLI_GLYPHS_MASK
)!=0 )
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 )
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
;
1834 /*************************************************************************
1835 * GetFontData [GDI32.@] Retrieve data for TrueType font
1839 * success: Number of bytes returned
1840 * failure: GDI_ERROR
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
;
1856 ret
= WineEngGetFontData(dc
->gdiFont
, table
, offset
, buffer
, length
);
1858 GDI_ReleaseObj(hdc
);
1862 /*************************************************************************
1863 * GetGlyphIndicesA [GDI32.@]
1865 DWORD WINAPI
GetGlyphIndicesA(HDC hdc
, LPCSTR lpstr
, INT count
,
1866 LPWORD pgi
, DWORD flags
)
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
);
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
;
1897 ret
= WineEngGetGlyphIndices(dc
->gdiFont
, lpstr
, count
, pgi
, flags
);
1899 GDI_ReleaseObj(hdc
);
1903 /*************************************************************************
1904 * GetCharacterPlacementA [GDI32.@]
1907 * the web browser control of ie4 calls this with dwFlags=0
1910 GetCharacterPlacementA(HDC hdc
, LPCSTR lpString
, INT uCount
,
1911 INT nMaxExtent
, GCP_RESULTSA
*lpResults
,
1916 GCP_RESULTSW resultsW
;
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
);
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
);
1947 /*************************************************************************
1948 * GetCharacterPlacementW [GDI32.@]
1950 * Retrieve information about a string. This includes the width, reordering,
1951 * Glyphing and so on.
1955 * The width and height of the string if succesful, 0 if failed.
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.
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 */
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
;
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)
2018 /* Keep a static table that translates the C2 types to something meaningful */
2019 /* 1 - left to right
2020 * -1 - right to left
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
);
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
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 )
2053 if(lpResults
->lpOutString
)
2056 for( j
=0; j
<run_end
; j
++ )
2058 lpResults
->lpOutString
[i
+j
]=lpString
[i
+j
];
2062 if(lpResults
->lpOrder
)
2065 for( j
=0; j
<run_end
; j
++ )
2066 lpResults
->lpOrder
[i
+j
] = i
+j
;
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 )
2079 if(lpResults
->lpOutString
)
2082 for( j
=0; j
<run_end
; j
++ )
2084 lpResults
->lpOutString
[i
+j
]=lpString
[i
+run_end
-j
-1];
2088 if(lpResults
->lpOrder
)
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
)
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
);
2120 /*************************************************************************
2121 * GetCharABCWidthsFloatA [GDI32.@]
2123 BOOL WINAPI
GetCharABCWidthsFloatA(HDC hdc
, UINT iFirstChar
, UINT iLastChar
,
2126 FIXME_(gdi
)("GetCharABCWidthsFloatA, stub\n");
2130 /*************************************************************************
2131 * GetCharABCWidthsFloatW [GDI32.@]
2133 BOOL WINAPI
GetCharABCWidthsFloatW(HDC hdc
, UINT iFirstChar
,
2134 UINT iLastChar
, LPABCFLOAT lpABCF
)
2136 FIXME_(gdi
)("GetCharABCWidthsFloatW, stub\n");
2140 /*************************************************************************
2141 * GetCharWidthFloatA [GDI32.@]
2143 BOOL WINAPI
GetCharWidthFloatA(HDC hdc
, UINT iFirstChar
,
2144 UINT iLastChar
, PFLOAT pxBuffer
)
2146 FIXME_(gdi
)("GetCharWidthFloatA, stub\n");
2150 /*************************************************************************
2151 * GetCharWidthFloatW [GDI32.@]
2153 BOOL WINAPI
GetCharWidthFloatW(HDC hdc
, UINT iFirstChar
,
2154 UINT iLastChar
, PFLOAT pxBuffer
)
2156 FIXME_(gdi
)("GetCharWidthFloatW, stub\n");
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
));
2193 MultiByteToWideChar(CP_ACP
, 0, str
, -1, strW
, len
);
2194 ret
= AddFontResourceExW(strW
, fl
, pdv
);
2195 HeapFree(GetProcessHeap(), 0, strW
);
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
));
2232 MultiByteToWideChar(CP_ACP
, 0, str
, -1, strW
, len
);
2233 ret
= RemoveFontResourceExW(strW
, fl
, pdv
);
2234 HeapFree(GetProcessHeap(), 0, strW
);
2238 /***********************************************************************
2239 * RemoveFontResourceExW (GDI32.@)
2241 BOOL WINAPI
RemoveFontResourceExW( LPCWSTR str
, DWORD fl
, PVOID pdv
)
2243 return WineEngRemoveFontResourceEx(str
, fl
, pdv
);