Fixed the behavior for SHGetFileInfo when the SHGFI_USEFILEATTRIBUTES
[wine] / objects / text.c
1 /*
2  * text functions
3  *
4  * Copyright 1993, 1994 Alexandre Julliard
5  *
6  */
7
8 #include <string.h>
9
10 #include "windef.h"
11 #include "wingdi.h"
12 #include "wine/winuser16.h"
13 #include "winbase.h"
14 #include "winerror.h"
15 #include "gdi.h"
16 #include "debugtools.h"
17 #include "winnls.h"
18
19 DEFAULT_DEBUG_CHANNEL(text);
20
21 /***********************************************************************
22  *           FONT_mbtowc
23  *
24  * Returns a '\0' terminated Unicode translation of str using the
25  * charset of the currently selected font in hdc.  If count is -1 then
26  * str is assumed to be '\0' terminated, otherwise it contains the
27  * number of bytes to convert.  If plenW is non-NULL, on return it
28  * will point to the number of WCHARs (excluding the '\0') that have
29  * been written.  If pCP is non-NULL, on return it will point to the
30  * codepage used in the conversion.  The caller should free the
31  * returned LPWSTR from the process heap itself.
32  */
33 LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
34 {
35     UINT cp = CP_ACP;
36     INT lenW;
37     LPWSTR strW;
38     CHARSETINFO csi;
39     int charset = GetTextCharset(hdc);
40
41     /* Hmm, nicely designed api this one! */
42     if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET))
43         cp = csi.ciACP;
44     else {
45         switch(charset) {
46         case SYMBOL_CHARSET:
47             cp = CP_SYMBOL;
48             break;
49         case OEM_CHARSET:
50             cp = GetOEMCP();
51             break;
52         case DEFAULT_CHARSET:
53             cp = GetACP();
54             break;
55
56         case VISCII_CHARSET:
57         case TCVN_CHARSET:
58         case KOI8_CHARSET:
59         case ISO3_CHARSET:
60         case ISO4_CHARSET:
61         case ISO10_CHARSET:
62         case CELTIC_CHARSET:
63           /* FIXME: These have no place here, but because x11drv
64              enumerates fonts with these (made up) charsets some apps
65              might use them and then the FIXME below would become
66              annoying.  Now we could pick the intended codepage for
67              each of these, but since it's broken anyway we'll just
68              use CP_ACP and hope it'll go away...
69           */
70             cp = CP_ACP;
71             break;
72
73
74         default:
75             FIXME("Can't find codepage for charset %d\n", charset);
76             break;
77         }
78     }
79
80     lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
81     strW = HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
82     MultiByteToWideChar(cp, 0, str, count, strW, lenW);
83     strW[lenW] = '\0';
84     if(plenW) *plenW = lenW;
85     if(pCP) *pCP = cp;
86     return strW;
87 }
88
89 /***********************************************************************
90  *           ExtTextOut (GDI.351)
91  */
92 BOOL16 WINAPI ExtTextOut16( HDC16 hdc, INT16 x, INT16 y, UINT16 flags,
93                             const RECT16 *lprect, LPCSTR str, UINT16 count,
94                             const INT16 *lpDx )
95 {
96     BOOL        ret;
97     int         i;
98     RECT        rect32;
99     LPINT       lpdx32 = NULL;
100
101     if (lpDx) {
102         lpdx32 = (LPINT)HeapAlloc( GetProcessHeap(),0, sizeof(INT)*count );
103         if(lpdx32 == NULL) return FALSE;
104         for (i=count;i--;) lpdx32[i]=lpDx[i];
105     }    
106     if (lprect) CONV_RECT16TO32(lprect,&rect32);
107     ret = ExtTextOutA(hdc,x,y,flags,lprect?&rect32:NULL,str,count,lpdx32);
108     if (lpdx32) HeapFree( GetProcessHeap(), 0, lpdx32 );
109     return ret;
110 }
111
112
113 /***********************************************************************
114  *           ExtTextOutA    (GDI32.@)
115  */
116 BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
117                          const RECT *lprect, LPCSTR str, UINT count, const INT *lpDx )
118 {
119     INT wlen;
120     UINT codepage;
121     LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
122     BOOL ret;
123     LPINT lpDxW = NULL;
124
125     if (lpDx) {
126         unsigned int i = 0, j = 0;
127
128         lpDxW = (LPINT)HeapAlloc( GetProcessHeap(), 0, wlen*sizeof(INT));
129         while(i < count) {
130             if(IsDBCSLeadByteEx(codepage, str[i])) {
131                 lpDxW[j++] = lpDx[i] + lpDx[i+1];
132                 i = i + 2;
133             } else {
134                 lpDxW[j++] = lpDx[i];
135                 i = i + 1;
136             }
137         }
138     }
139
140     ret = ExtTextOutW( hdc, x, y, flags, lprect, p, wlen, lpDxW );
141
142     HeapFree( GetProcessHeap(), 0, p );
143     if (lpDxW) HeapFree( GetProcessHeap(), 0, lpDxW );
144     return ret;
145 }
146
147
148 /***********************************************************************
149  *           ExtTextOutW    (GDI32.@)
150  */
151 BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
152                          const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
153 {
154     BOOL ret = FALSE;
155     DC * dc = DC_GetDCUpdate( hdc );
156     if (dc)
157     {
158         if(dc->funcs->pExtTextOut)
159             ret = dc->funcs->pExtTextOut(dc,x,y,flags,lprect,str,count,lpDx);
160         GDI_ReleaseObj( hdc );
161     }
162     return ret;
163 }
164
165
166 /***********************************************************************
167  *           TextOut    (GDI.33)
168  */
169 BOOL16 WINAPI TextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR str, INT16 count )
170 {
171     return ExtTextOut16( hdc, x, y, 0, NULL, str, count, NULL );
172 }
173
174
175 /***********************************************************************
176  *           TextOutA    (GDI32.@)
177  */
178 BOOL WINAPI TextOutA( HDC hdc, INT x, INT y, LPCSTR str, INT count )
179 {
180     return ExtTextOutA( hdc, x, y, 0, NULL, str, count, NULL );
181 }
182
183
184 /***********************************************************************
185  *           TextOutW    (GDI32.@)
186  */
187 BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count)
188 {
189     return ExtTextOutW( hdc, x, y, 0, NULL, str, count, NULL );
190 }
191
192
193 /***********************************************************************
194  * GetTextCharset [GDI32.@]  Gets character set for font in DC
195  *
196  * NOTES
197  *    Should it return a UINT32 instead of an INT32?
198  *    => YES, as GetTextCharsetInfo returns UINT32
199  *
200  * RETURNS
201  *    Success: Character set identifier
202  *    Failure: DEFAULT_CHARSET
203  */
204 UINT WINAPI GetTextCharset(
205     HDC hdc) /* [in] Handle to device context */
206 {
207     /* MSDN docs say this is equivalent */
208     return GetTextCharsetInfo(hdc, NULL, 0);
209 }
210
211 /***********************************************************************
212  * GetTextCharset [GDI.612]
213  */
214 UINT16 WINAPI GetTextCharset16(HDC16 hdc)
215 {
216     return (UINT16)GetTextCharset(hdc);
217 }
218
219 /***********************************************************************
220  * GetTextCharsetInfo [GDI32.@]  Gets character set for font
221  *
222  * NOTES
223  *    Should csi be an LPFONTSIGNATURE instead of an LPCHARSETINFO?
224  *    Should it return a UINT32 instead of an INT32?
225  *    => YES and YES, from win32.hlp from Borland
226  *
227  *    This returns the actual charset selected by the driver rather than the
228  *    value in lf.lfCharSet during CreateFont, to get that use
229  *    GetObject(GetCurrentObject(...),...)
230  *
231  * RETURNS
232  *    Success: Character set identifier
233  *    Failure: DEFAULT_CHARSET
234  */
235 UINT WINAPI GetTextCharsetInfo(
236     HDC hdc,            /* [in]  Handle to device context */
237     LPFONTSIGNATURE fs, /* [out] Pointer to struct to receive data */
238     DWORD flags)        /* [in]  Reserved - must be 0 */
239 {
240     UINT charSet = DEFAULT_CHARSET;
241     CHARSETINFO csinfo;
242     TEXTMETRICW tm;
243
244     if(!GetTextMetricsW(hdc, &tm)) return DEFAULT_CHARSET;
245     charSet = tm.tmCharSet;
246
247     if (fs != NULL) {
248       if (!TranslateCharsetInfo((LPDWORD)charSet, &csinfo, TCI_SRCCHARSET))
249            return DEFAULT_CHARSET;
250       memcpy(fs, &csinfo.fs, sizeof(FONTSIGNATURE));
251     }
252     return charSet;
253 }
254
255 /***********************************************************************
256  *              PolyTextOutA (GDI32.@)
257  *
258  * Draw several Strings
259  */
260 BOOL WINAPI PolyTextOutA (
261                           HDC hdc,               /* [in] Handle to device context */                      
262                           PPOLYTEXTA pptxt,      /* [in] Array of strings */
263                           INT cStrings           /* [in] Number of strings in array */
264                           )
265 {
266   FIXME("stub!\n");
267   SetLastError ( ERROR_CALL_NOT_IMPLEMENTED );
268   return 0;
269 }
270
271
272
273 /***********************************************************************
274  *              PolyTextOutW (GDI32.@)
275  *
276  * Draw several Strings
277  */
278 BOOL WINAPI PolyTextOutW ( 
279                           HDC hdc,               /* [in] Handle to device context */                      
280                           PPOLYTEXTW pptxt,      /* [in] Array of strings */
281                           INT cStrings           /* [in] Number of strings in array */
282                           )
283 {
284   FIXME("stub!\n");
285   SetLastError ( ERROR_CALL_NOT_IMPLEMENTED );
286   return 0;
287 }