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