update for HEAD-2003091401
[reactos.git] / lib / gdi32 / objects / text.c
1 #ifdef UNICODE
2 #undef UNICODE
3 #endif
4
5 #undef WIN32_LEAN_AND_MEAN
6 #include <string.h>
7 #include <windows.h>
8 #include <ddk/ntddk.h>
9 #include <win32k/kapi.h>
10
11
12 /*
13  * @implemented
14  */
15 UINT
16 STDCALL
17 SetTextAlign(
18         HDC     a0,
19         UINT    a1
20         )
21 {
22         return NtGdiSetTextAlign(a0, a1);
23 }
24
25
26 /*
27  * @implemented
28  */
29 BOOL  
30 STDCALL 
31 TextOutA(
32         HDC  hDC,
33         int  XStart,
34         int  YStart,
35         LPCSTR  String,
36         int  Count)
37 {
38         ANSI_STRING StringA;
39         UNICODE_STRING StringU;
40         BOOL ret;
41
42         if (NULL != String)
43         {
44                 RtlInitAnsiString(&StringA, (LPSTR)String);
45                 RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
46         } else
47                 StringU.Buffer = NULL;
48
49         ret = TextOutW(hDC, XStart, YStart, StringU.Buffer, Count);
50         RtlFreeUnicodeString(&StringU);
51         return ret;
52 }
53
54
55 /*
56  * @implemented
57  */
58 BOOL
59 STDCALL
60 TextOutW(
61         HDC  hDC,
62         int  XStart,
63         int  YStart,
64         LPCWSTR  String,
65         int  Count)
66 {
67         return NtGdiTextOut(hDC, XStart, YStart, String, Count);
68 }
69
70
71 /*
72  * @implemented
73  */
74 COLORREF  STDCALL 
75 SetTextColor(HDC hDC, COLORREF color)
76 {
77   return(NtGdiSetTextColor(hDC, color));
78 }
79
80
81 static BOOL
82 MetricsCharConvert(WCHAR w, CHAR *b)
83   {
84   UNICODE_STRING WString;
85   WCHAR WBuf[2];
86   ANSI_STRING AString;
87   CHAR ABuf[2];
88   NTSTATUS Status;
89
90   if (L'\0' == w)
91     {
92       *b = '\0';
93     }
94   else
95     {
96       WBuf[0] = w;
97       WBuf[1] = L'\0';
98       RtlInitUnicodeString(&WString, WBuf);
99       ABuf[0] = '*';
100       ABuf[1] = L'\0';
101       RtlInitAnsiString(&AString, ABuf);
102
103       Status = RtlUnicodeStringToAnsiString(&AString, &WString, FALSE);
104       if (! NT_SUCCESS(Status))
105         {
106           SetLastError(RtlNtStatusToDosError(Status));
107           return FALSE;
108         }
109       *b = ABuf[0];
110     }
111
112   return TRUE;
113   }
114
115
116 /*
117  * @implemented
118  */
119 BOOL 
120 STDCALL 
121 GetTextMetricsA(
122         HDC             hdc, 
123         LPTEXTMETRICA   tm
124         )
125 {
126   TEXTMETRICW tmw;
127   UNICODE_STRING WString;
128   WCHAR WBuf[256];
129   ANSI_STRING AString;
130   CHAR ABuf[256];
131   UINT Letter;
132   NTSTATUS Status;
133
134   if (! NtGdiGetTextMetrics(hdc, &tmw))
135     {
136       return FALSE;
137     }
138
139   tm->tmHeight = tmw.tmHeight;
140   tm->tmAscent = tmw.tmAscent;
141   tm->tmDescent = tmw.tmDescent;
142   tm->tmInternalLeading = tmw.tmInternalLeading;
143   tm->tmExternalLeading = tmw.tmExternalLeading;
144   tm->tmAveCharWidth = tmw.tmAveCharWidth;
145   tm->tmMaxCharWidth = tmw.tmMaxCharWidth;
146   tm->tmWeight = tmw.tmWeight;
147   tm->tmOverhang = tmw.tmOverhang;
148   tm->tmDigitizedAspectX = tmw.tmDigitizedAspectX;
149   tm->tmDigitizedAspectY = tmw.tmDigitizedAspectY;
150
151   /* The Unicode FirstChar/LastChar need not correspond to the ANSI
152      FirstChar/LastChar. For example, if the font contains glyphs for
153      letters A-Z and an accented version of the letter e, the Unicode
154      FirstChar would be A and the Unicode LastChar would be the accented
155      e. If you just translate those to ANSI, the range would become
156      letters A-E instead of A-Z.
157      We translate all possible ANSI chars to Unicode and find the first
158      and last translated character which fall into the Unicode FirstChar/
159      LastChar range and return the corresponding ANSI char. */
160
161   /* Setup an Ansi string containing all possible letters (note: skip '\0' at
162      the beginning since that would be interpreted as end-of-string, handle
163      '\0' special later */
164   for (Letter = 1; Letter < 256; Letter++)
165     {
166     ABuf[Letter - 1] = (CHAR) Letter;
167     WBuf[Letter - 1] = L' ';
168     }
169   ABuf[255] = '\0';
170   WBuf[255] = L'\0';
171   RtlInitAnsiString(&AString, ABuf);
172   RtlInitUnicodeString(&WString, WBuf);
173
174   /* Find the corresponding Unicode characters */
175   Status = RtlAnsiStringToUnicodeString(&WString, &AString, FALSE);
176   if (! NT_SUCCESS(Status))
177     {
178       SetLastError(RtlNtStatusToDosError(Status));
179       return FALSE;
180     }
181
182   /* Scan for the first ANSI character which maps to an Unicode character
183      in the range */
184   tm->tmFirstChar = '\0';
185   if (L'\0' != tmw.tmFirstChar)
186     {
187       for (Letter = 1; Letter < 256; Letter++)
188         {
189           if (tmw.tmFirstChar <= WBuf[Letter - 1] &&
190               WBuf[Letter - 1] <= tmw.tmLastChar)
191             {
192               tm->tmFirstChar = (CHAR) Letter;
193               break;
194             }
195         }
196     }
197
198   /* Scan for the last ANSI character which maps to an Unicode character
199      in the range */
200   tm->tmLastChar = '\0';
201   if (L'\0' != tmw.tmLastChar)
202     {
203       for (Letter = 255; 0 < Letter; Letter--)
204         {
205           if (tmw.tmFirstChar <= WBuf[Letter - 1] &&
206               WBuf[Letter - 1] <= tmw.tmLastChar)
207             {
208               tm->tmLastChar = (CHAR) Letter;
209               break;
210             }
211         }
212     }
213
214   if (! MetricsCharConvert(tmw.tmDefaultChar, &tm->tmDefaultChar) ||
215       ! MetricsCharConvert(tmw.tmBreakChar, &tm->tmBreakChar))
216     {
217       return FALSE;
218     }
219
220   tm->tmItalic = tmw.tmItalic;
221   tm->tmUnderlined = tmw.tmUnderlined;
222   tm->tmStruckOut = tmw.tmStruckOut;
223   tm->tmPitchAndFamily = tmw.tmPitchAndFamily;
224   tm->tmCharSet = tmw.tmCharSet;
225
226   return TRUE;
227 }
228
229
230 /*
231  * @implemented
232  */
233 BOOL 
234 STDCALL 
235 GetTextMetricsW(
236         HDC             hdc, 
237         LPTEXTMETRICW   tm
238         )
239 {
240         return NtGdiGetTextMetrics(hdc, tm);
241 }
242
243
244 /*
245  * @implemented
246  */
247 BOOL
248 APIENTRY
249 GetTextExtentPointA(
250         HDC             hDC,
251         LPCSTR          String,
252         int             Count,
253         LPSIZE          Size
254         )
255 {
256         ANSI_STRING StringA;
257         UNICODE_STRING StringU;
258         BOOL ret;
259
260         RtlInitAnsiString(&StringA, (LPSTR)String);
261         RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
262
263         ret = GetTextExtentPointW(hDC, StringU.Buffer, Count, Size);
264
265         RtlFreeUnicodeString(&StringU);
266
267         return ret;
268 }
269
270
271 /*
272  * @implemented
273  */
274 BOOL
275 APIENTRY
276 GetTextExtentPointW(
277         HDC             hDC,
278         LPCWSTR         String,
279         int             Count,
280         LPSIZE          Size
281         )
282 {
283         return NtGdiGetTextExtentPoint(hDC, String, Count, Size);
284 }
285
286
287 /*
288  * @implemented
289  */
290 BOOL
291 APIENTRY
292 GetTextExtentPoint32A(
293         HDC             hDC,
294         LPCSTR          String,
295         int             Count,
296         LPSIZE          Size
297         )
298 {
299   ANSI_STRING StringA;
300   UNICODE_STRING StringU;
301   BOOL ret;
302
303   RtlInitAnsiString(&StringA, (LPSTR)String);
304   RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
305
306   ret = GetTextExtentPoint32W(hDC, StringU.Buffer, Count, Size);
307
308   RtlFreeUnicodeString(&StringU);
309
310   return ret;
311 }
312
313
314 /*
315  * @implemented
316  */
317 BOOL
318 APIENTRY
319 GetTextExtentPoint32W(
320         HDC             hDC,
321         LPCWSTR         String,
322         int             Count,
323         LPSIZE          Size
324         )
325 {
326   return NtGdiGetTextExtentPoint32(hDC, String, Count, Size);
327 }
328
329
330 /*
331  * @implemented
332  */
333 BOOL  
334 STDCALL 
335 ExtTextOutA(
336         HDC             hDC, 
337         int             X, 
338         int             Y, 
339         UINT            Options, 
340         CONST RECT      *Rect,
341         LPCSTR          String, 
342         UINT            Count, 
343         CONST INT       *Spacings
344         )
345 {
346         ANSI_STRING StringA;
347         UNICODE_STRING StringU;
348         BOOL ret;
349
350         RtlInitAnsiString(&StringA, (LPSTR)String);
351         RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
352
353         ret = ExtTextOutW(hDC, X, Y, Options, Rect, StringU.Buffer, Count, Spacings);
354
355         RtlFreeUnicodeString(&StringU);
356
357         return ret;
358 }
359
360
361 /*
362  * @implemented
363  */
364 BOOL  
365 STDCALL 
366 ExtTextOutW(
367         HDC             hDC, 
368         int             X, 
369         int             Y, 
370         UINT            Options,         
371         CONST RECT      *Rect,
372         LPCWSTR         String, 
373         UINT            Count, 
374         CONST INT       *Spacings
375         )
376 {
377         return NtGdiTextOut(hDC, X, Y, String, Count);
378 }
379
380
381 /*
382  * @implemented
383  */
384 HFONT
385 STDCALL
386 CreateFontIndirectA(
387         CONST LOGFONTA          *lf
388         )
389 {
390         ANSI_STRING StringA;
391         UNICODE_STRING StringU;
392         HFONT ret;
393         LOGFONTW tlf;
394
395         RtlInitAnsiString(&StringA, (LPSTR)lf->lfFaceName);
396         RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
397         memcpy(&tlf, lf, sizeof(LOGFONTA));
398         memcpy(&tlf.lfFaceName, &StringU.Buffer, StringU.Length);
399
400         ret = CreateFontIndirectW(&tlf);
401
402         RtlFreeUnicodeString(&StringU);
403
404         return ret;
405 }
406
407
408 /*
409  * @implemented
410  */
411 HFONT
412 STDCALL
413 CreateFontIndirectW(
414         CONST LOGFONTW          *lf
415         )
416 {
417         return NtGdiCreateFontIndirect((CONST LPLOGFONTW)lf);
418 }
419
420
421 /*
422  * @implemented
423  */
424 HFONT
425 STDCALL
426 CreateFontA(
427         int     Height,
428         int     Width,
429         int     Escapement,
430         int     Orientation,
431         int     Weight,
432         DWORD   Italic,
433         DWORD   Underline,
434         DWORD   StrikeOut,
435         DWORD   CharSet,
436         DWORD   OutputPrecision,
437         DWORD   ClipPrecision,
438         DWORD   Quality,
439         DWORD   PitchAndFamily,
440         LPCSTR  Face
441         )
442 {
443         ANSI_STRING StringA;
444         UNICODE_STRING StringU;
445         HFONT ret;
446
447         RtlInitAnsiString(&StringA, (LPSTR)Face);
448         RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
449
450         ret = CreateFontW(Height, Width, Escapement, Orientation, Weight, Italic, Underline, StrikeOut,
451                           CharSet, OutputPrecision, ClipPrecision, Quality, PitchAndFamily, StringU.Buffer);
452
453         RtlFreeUnicodeString(&StringU);
454
455         return ret;
456 }
457
458
459 /*
460  * @implemented
461  */
462 HFONT
463 STDCALL
464 CreateFontW(
465         int     Height,
466         int     Width,
467         int     Escapement,
468         int     Orientation,
469         int     Weight,
470         DWORD   Italic,
471         DWORD   Underline,
472         DWORD   StrikeOut,
473         DWORD   CharSet,
474         DWORD   OutputPrecision,
475         DWORD   ClipPrecision,
476         DWORD   Quality,
477         DWORD   PitchAndFamily,
478         LPCWSTR Face
479         )
480 {
481         return NtGdiCreateFont(Height, Width, Escapement, Orientation, Weight, Italic, Underline, StrikeOut,
482                           CharSet, OutputPrecision, ClipPrecision, Quality, PitchAndFamily, Face);
483 }
484