Handle context in CreateURLMoniker.
[wine] / objects / text.c
1 /*
2  * text functions
3  *
4  * Copyright 1993, 1994 Alexandre Julliard
5  * Copyright 2003 Shachar Shemesh
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdarg.h>
23 #include <string.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "wine/winuser16.h"
29 #include "winerror.h"
30 #include "winnls.h"
31 #include "gdi.h"
32 #include "gdi_private.h"
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(text);
36
37 /***********************************************************************
38  *           FONT_mbtowc
39  *
40  * Returns a '\0' terminated Unicode translation of str using the
41  * charset of the currently selected font in hdc.  If count is -1 then
42  * str is assumed to be '\0' terminated, otherwise it contains the
43  * number of bytes to convert.  If plenW is non-NULL, on return it
44  * will point to the number of WCHARs (excluding the '\0') that have
45  * been written.  If pCP is non-NULL, on return it will point to the
46  * codepage used in the conversion.
47  * The caller should free the returned LPWSTR from the process
48  * heap itself.
49  */
50 LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
51 {
52     UINT cp = CP_ACP;
53     INT lenW;
54     LPWSTR strW;
55     CHARSETINFO csi;
56     int charset = GetTextCharset(hdc);
57
58     /* Hmm, nicely designed api this one! */
59     if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET))
60         cp = csi.ciACP;
61     else {
62         switch(charset) {
63         case OEM_CHARSET:
64             cp = GetOEMCP();
65             break;
66         case DEFAULT_CHARSET:
67             cp = GetACP();
68             break;
69
70         case VISCII_CHARSET:
71         case TCVN_CHARSET:
72         case KOI8_CHARSET:
73         case ISO3_CHARSET:
74         case ISO4_CHARSET:
75         case ISO10_CHARSET:
76         case CELTIC_CHARSET:
77           /* FIXME: These have no place here, but because x11drv
78              enumerates fonts with these (made up) charsets some apps
79              might use them and then the FIXME below would become
80              annoying.  Now we could pick the intended codepage for
81              each of these, but since it's broken anyway we'll just
82              use CP_ACP and hope it'll go away...
83           */
84             cp = CP_ACP;
85             break;
86
87
88         default:
89             FIXME("Can't find codepage for charset %d\n", charset);
90             break;
91         }
92     }
93
94     TRACE("charset %d => cp %d\n", charset, cp);
95
96     if(count == -1) count = strlen(str);
97     lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
98     strW = HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
99     MultiByteToWideChar(cp, 0, str, count, strW, lenW);
100     strW[lenW] = '\0';
101     TRACE("mapped %s -> %s\n", debugstr_an(str, count), debugstr_wn(strW, lenW));
102     if(plenW) *plenW = lenW;
103     if(pCP) *pCP = cp;
104     return strW;
105 }
106
107
108 /***********************************************************************
109  *           ExtTextOutA    (GDI32.@)
110  */
111 BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
112                          const RECT *lprect, LPCSTR str, UINT count, const INT *lpDx )
113 {
114     INT wlen;
115     UINT codepage;
116     LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
117     BOOL ret;
118     LPINT lpDxW = NULL;
119
120     if (lpDx) {
121         unsigned int i = 0, j = 0;
122
123         lpDxW = (LPINT)HeapAlloc( GetProcessHeap(), 0, wlen*sizeof(INT));
124         while(i < count) {
125             if(IsDBCSLeadByteEx(codepage, str[i])) {
126                 lpDxW[j++] = lpDx[i] + lpDx[i+1];
127                 i = i + 2;
128             } else {
129                 lpDxW[j++] = lpDx[i];
130                 i = i + 1;
131             }
132         }
133     }
134
135     ret = ExtTextOutW( hdc, x, y, flags, lprect, p, wlen, lpDxW );
136
137     HeapFree( GetProcessHeap(), 0, p );
138     if (lpDxW) HeapFree( GetProcessHeap(), 0, lpDxW );
139     return ret;
140 }
141
142
143 /***********************************************************************
144  *           ExtTextOutW    (GDI32.@)
145  */
146 BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
147                          const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
148 {
149     BOOL ret = FALSE;
150     DC * dc = DC_GetDCUpdate( hdc );
151     if (dc)
152     {
153         if(PATH_IsPathOpen(dc->path))
154             FIXME("called on an open path\n");
155         else if(dc->funcs->pExtTextOut)
156         {
157             if( !(flags&(ETO_GLYPH_INDEX|ETO_IGNORELANGUAGE)) && BidiAvail && count>0 )
158             {
159                 /* The caller did not specify that language processing was already done.
160                  */
161                 LPWSTR lpReorderedString=HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
162
163                 BIDI_Reorder( str, count, GCP_REORDER,
164                               ((flags&ETO_RTLREADING)!=0 || (GetTextAlign(hdc)&TA_RTLREADING)!=0)?
165                               WINE_GCPW_FORCE_RTL:WINE_GCPW_FORCE_LTR,
166                               lpReorderedString, count, NULL );
167
168                 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags|ETO_IGNORELANGUAGE,
169                                              lprect,lpReorderedString,count,lpDx,dc->breakExtra);
170                 HeapFree(GetProcessHeap(), 0, lpReorderedString);
171             } else
172                 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags,lprect,str,count,
173                                              lpDx,dc->breakExtra);
174         }
175         GDI_ReleaseObj( hdc );
176     }
177     return ret;
178 }
179
180
181 /***********************************************************************
182  *           TextOutA    (GDI32.@)
183  */
184 BOOL WINAPI TextOutA( HDC hdc, INT x, INT y, LPCSTR str, INT count )
185 {
186     return ExtTextOutA( hdc, x, y, 0, NULL, str, count, NULL );
187 }
188
189
190 /***********************************************************************
191  *           TextOutW    (GDI32.@)
192  */
193 BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count)
194 {
195     return ExtTextOutW( hdc, x, y, 0, NULL, str, count, NULL );
196 }
197
198
199 /***********************************************************************
200  *              PolyTextOutA (GDI32.@)
201  *
202  * Draw several Strings
203  */
204 BOOL WINAPI PolyTextOutA (
205                           HDC hdc,               /* [in] Handle to device context */
206                           PPOLYTEXTA pptxt,      /* [in] Array of strings */
207                           INT cStrings           /* [in] Number of strings in array */
208                           )
209 {
210     for (; cStrings>0; cStrings--, pptxt++)
211         if (!ExtTextOutA( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
212             return FALSE;
213     return TRUE;
214 }
215
216
217
218 /***********************************************************************
219  *              PolyTextOutW (GDI32.@)
220  *
221  * Draw several Strings
222  */
223 BOOL WINAPI PolyTextOutW (
224                           HDC hdc,               /* [in] Handle to device context */
225                           PPOLYTEXTW pptxt,      /* [in] Array of strings */
226                           INT cStrings           /* [in] Number of strings in array */
227                           )
228 {
229     for (; cStrings>0; cStrings--, pptxt++)
230         if (!ExtTextOutW( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
231             return FALSE;
232     return TRUE;
233 }