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