blob: 7a467ad064d3fcc161d98b664cfcd5e13bcf0aa6 [file] [log] [blame]
Alexandre Julliard401710d1993-09-04 10:09:32 +00001/*
2 * text functions
3 *
Alexandre Julliardaca05781994-10-17 18:12:41 +00004 * Copyright 1993, 1994 Alexandre Julliard
Alexandre Julliard234bc241994-12-10 13:02:28 +00005 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00006 * 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
Alexandre Julliard7e56f681996-01-31 19:02:28 +000019 */
20
David Luyeree517e81999-02-28 12:27:56 +000021#include <string.h>
Patrik Stridvallfdcfdb91999-06-12 14:55:11 +000022
Jeremy Whited3e22d92000-02-10 19:03:02 +000023#include "windef.h"
24#include "wingdi.h"
Patrik Stridvallfdcfdb91999-06-12 14:55:11 +000025#include "wine/winuser16.h"
Michael Vekslerff5ae3d1999-04-22 15:26:11 +000026#include "winbase.h"
Peter Ganten87d95b71999-09-19 14:17:14 +000027#include "winerror.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000028#include "gdi.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000029#include "wine/debug.h"
Hidenori Takeshimae2905ea2000-03-26 14:43:22 +000030#include "winnls.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000031
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000032WINE_DEFAULT_DEBUG_CHANNEL(text);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000033
Huw D M Davies29382422001-09-19 20:32:07 +000034/***********************************************************************
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
Huw D M Davies8da26fb2002-06-22 01:19:29 +000043 * 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.
Huw D M Davies29382422001-09-19 20:32:07 +000046 */
47LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
48{
Huw D M Davies29382422001-09-19 20:32:07 +000049 UINT cp = CP_ACP;
Huw D M Davies8da26fb2002-06-22 01:19:29 +000050 INT lenW, i;
Huw D M Davies29382422001-09-19 20:32:07 +000051 LPWSTR strW;
52 CHARSETINFO csi;
Huw D M Daviesfef698c2001-10-10 20:25:04 +000053 int charset = GetTextCharset(hdc);
Huw D M Davies29382422001-09-19 20:32:07 +000054
55 /* Hmm, nicely designed api this one! */
Huw D M Daviesfef698c2001-10-10 20:25:04 +000056 if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET))
Huw D M Davies29382422001-09-19 20:32:07 +000057 cp = csi.ciACP;
58 else {
Huw D M Daviesfef698c2001-10-10 20:25:04 +000059 switch(charset) {
Huw D M Davies29382422001-09-19 20:32:07 +000060 case OEM_CHARSET:
61 cp = GetOEMCP();
62 break;
Huw D M Davies848bc152001-09-20 18:58:05 +000063 case DEFAULT_CHARSET:
64 cp = GetACP();
65 break;
Huw D M Davies29382422001-09-19 20:32:07 +000066
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:
Francois Gouget58b299522001-10-08 20:40:09 +000074 /* FIXME: These have no place here, but because x11drv
Huw D M Davies29382422001-09-19 20:32:07 +000075 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:
Huw D M Daviesfef698c2001-10-10 20:25:04 +000086 FIXME("Can't find codepage for charset %d\n", charset);
Huw D M Davies29382422001-09-19 20:32:07 +000087 break;
88 }
89 }
90
Huw D M Davies8da26fb2002-06-22 01:19:29 +000091 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 }
Huw D M Davies29382422001-09-19 20:32:07 +0000103 strW[lenW] = '\0';
Huw D M Davies8da26fb2002-06-22 01:19:29 +0000104 TRACE("mapped %s -> %s\n", debugstr_an(str, count), debugstr_wn(strW, lenW));
Huw D M Davies29382422001-09-19 20:32:07 +0000105 if(plenW) *plenW = lenW;
106 if(pCP) *pCP = cp;
107 return strW;
108}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000109
Alexandre Julliardaca05781994-10-17 18:12:41 +0000110
111/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000112 * ExtTextOutA (GDI32.@)
Alexandre Julliardaca05781994-10-17 18:12:41 +0000113 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000114BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
Huw D M Davies29382422001-09-19 20:32:07 +0000115 const RECT *lprect, LPCSTR str, UINT count, const INT *lpDx )
Alexandre Julliardaca05781994-10-17 18:12:41 +0000116{
Huw D M Davies29382422001-09-19 20:32:07 +0000117 INT wlen;
118 UINT codepage;
119 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
120 BOOL ret;
Junichi Kuchinishi34b7b3f2000-04-06 20:12:16 +0000121 LPINT lpDxW = NULL;
Hidenori Takeshimae2905ea2000-03-26 14:43:22 +0000122
Huw D M Davies29382422001-09-19 20:32:07 +0000123 if (lpDx) {
124 unsigned int i = 0, j = 0;
Junichi Kuchinishi34b7b3f2000-04-06 20:12:16 +0000125
Huw D M Davies29382422001-09-19 20:32:07 +0000126 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 }
Junichi Kuchinishi34b7b3f2000-04-06 20:12:16 +0000136 }
Huw D M Davies29382422001-09-19 20:32:07 +0000137
138 ret = ExtTextOutW( hdc, x, y, flags, lprect, p, wlen, lpDxW );
139
140 HeapFree( GetProcessHeap(), 0, p );
141 if (lpDxW) HeapFree( GetProcessHeap(), 0, lpDxW );
Huw D M Daviesc5539241999-12-26 00:47:03 +0000142 return ret;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000143}
144
145
146/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000147 * ExtTextOutW (GDI32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000148 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000149BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
Huw D M Davies29382422001-09-19 20:32:07 +0000150 const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000151{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000152 BOOL ret = FALSE;
153 DC * dc = DC_GetDCUpdate( hdc );
154 if (dc)
155 {
Huw D M Davies8a326132002-04-06 00:37:50 +0000156 if(PATH_IsPathOpen(dc->path))
157 FIXME("called on an open path\n");
Shachar Shemesh4ebb7b52002-06-14 23:29:16 +0000158 else if(dc->funcs->pExtTextOut)
159 {
160 DWORD fontLangInfo=0;
161 if( !(flags&(ETO_GLYPH_INDEX|ETO_IGNORELANGUAGE)) &&
162 ((fontLangInfo=GetFontLanguageInfo( hdc ))&(GCP_REORDER|GCP_GLYPHSHAPE)) )
163 {
164 /* The caller did not specify that language processing was already done,
165 * and the font idetifies iteself as requiring language processing.
166 */
167 GCP_RESULTSW gcp;
Huw D M Daviesb4bdd812002-08-09 00:55:33 +0000168
Shachar Shemesh4ebb7b52002-06-14 23:29:16 +0000169 gcp.lStructSize=sizeof(gcp);
170 gcp.lpOutString=HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
171 gcp.lpOrder=NULL;
172 gcp.lpDx=NULL;
173 gcp.lpCaretPos=NULL;
174 gcp.lpClass=NULL;
175 gcp.lpGlyphs=NULL;
176 gcp.nGlyphs=0;
177 gcp.nMaxFit=0;
Huw D M Daviesb4bdd812002-08-09 00:55:33 +0000178
Shachar Shemesh4ebb7b52002-06-14 23:29:16 +0000179 GetCharacterPlacementW(hdc, str, count, 0, &gcp, GCP_REORDER );
Huw D M Daviesb4bdd812002-08-09 00:55:33 +0000180
Shachar Shemesh4ebb7b52002-06-14 23:29:16 +0000181 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags|ETO_IGNORELANGUAGE,
182 lprect,gcp.lpOutString,count,lpDx);
Huw D M Daviesb4bdd812002-08-09 00:55:33 +0000183 HeapFree(GetProcessHeap(), 0, gcp.lpOutString);
Shachar Shemesh4ebb7b52002-06-14 23:29:16 +0000184 } else
185 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags,lprect,str,count,lpDx);
186 }
187 GDI_ReleaseObj( hdc );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000188 }
189 return ret;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000190}
191
192
193/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000194 * TextOutA (GDI32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000195 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000196BOOL WINAPI TextOutA( HDC hdc, INT x, INT y, LPCSTR str, INT count )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000197{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000198 return ExtTextOutA( hdc, x, y, 0, NULL, str, count, NULL );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000199}
200
201
202/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000203 * TextOutW (GDI32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000204 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000205BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000206{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000207 return ExtTextOutW( hdc, x, y, 0, NULL, str, count, NULL );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000208}
209
210
Alexandre Julliard58199531994-04-21 01:20:00 +0000211/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000212 * GetTextCharset [GDI32.@] Gets character set for font in DC
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000213 *
214 * NOTES
215 * Should it return a UINT32 instead of an INT32?
Gael de Chalendard5af0171998-11-22 12:19:49 +0000216 * => YES, as GetTextCharsetInfo returns UINT32
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000217 *
218 * RETURNS
219 * Success: Character set identifier
220 * Failure: DEFAULT_CHARSET
Alexandre Julliard33072e11997-06-29 18:08:02 +0000221 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000222UINT WINAPI GetTextCharset(
223 HDC hdc) /* [in] Handle to device context */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000224{
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000225 /* MSDN docs say this is equivalent */
226 return GetTextCharsetInfo(hdc, NULL, 0);
Alexandre Julliard33072e11997-06-29 18:08:02 +0000227}
228
Alexandre Julliarde658d821997-11-30 17:45:40 +0000229
230/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000231 * GetTextCharsetInfo [GDI32.@] Gets character set for font
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000232 *
233 * NOTES
234 * Should csi be an LPFONTSIGNATURE instead of an LPCHARSETINFO?
235 * Should it return a UINT32 instead of an INT32?
Gael de Chalendard5af0171998-11-22 12:19:49 +0000236 * => YES and YES, from win32.hlp from Borland
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000237 *
Huw D M Daviesfef698c2001-10-10 20:25:04 +0000238 * This returns the actual charset selected by the driver rather than the
239 * value in lf.lfCharSet during CreateFont, to get that use
240 * GetObject(GetCurrentObject(...),...)
241 *
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000242 * RETURNS
243 * Success: Character set identifier
244 * Failure: DEFAULT_CHARSET
Alexandre Julliarde658d821997-11-30 17:45:40 +0000245 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000246UINT WINAPI GetTextCharsetInfo(
Patrik Stridvall2b3aa612000-12-01 23:58:28 +0000247 HDC hdc, /* [in] Handle to device context */
Gael de Chalendard5af0171998-11-22 12:19:49 +0000248 LPFONTSIGNATURE fs, /* [out] Pointer to struct to receive data */
249 DWORD flags) /* [in] Reserved - must be 0 */
Alexandre Julliarde658d821997-11-30 17:45:40 +0000250{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000251 UINT charSet = DEFAULT_CHARSET;
Guy Albertelli53292171999-01-24 09:50:09 +0000252 CHARSETINFO csinfo;
Huw D M Daviesfef698c2001-10-10 20:25:04 +0000253 TEXTMETRICW tm;
Gael de Chalendard5af0171998-11-22 12:19:49 +0000254
Huw D M Daviesfef698c2001-10-10 20:25:04 +0000255 if(!GetTextMetricsW(hdc, &tm)) return DEFAULT_CHARSET;
256 charSet = tm.tmCharSet;
Gael de Chalendard5af0171998-11-22 12:19:49 +0000257
258 if (fs != NULL) {
Marcus Meissner03479f81999-01-28 10:06:38 +0000259 if (!TranslateCharsetInfo((LPDWORD)charSet, &csinfo, TCI_SRCCHARSET))
Huw D M Daviesfef698c2001-10-10 20:25:04 +0000260 return DEFAULT_CHARSET;
Guy Albertelli53292171999-01-24 09:50:09 +0000261 memcpy(fs, &csinfo.fs, sizeof(FONTSIGNATURE));
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000262 }
Gael de Chalendard5af0171998-11-22 12:19:49 +0000263 return charSet;
Alexandre Julliarde658d821997-11-30 17:45:40 +0000264}
Peter Ganten87d95b71999-09-19 14:17:14 +0000265
266/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000267 * PolyTextOutA (GDI32.@)
268 *
269 * Draw several Strings
Peter Ganten87d95b71999-09-19 14:17:14 +0000270 */
271BOOL WINAPI PolyTextOutA (
Vincent Béron9a624912002-05-31 23:06:46 +0000272 HDC hdc, /* [in] Handle to device context */
Patrik Stridvall2b3aa612000-12-01 23:58:28 +0000273 PPOLYTEXTA pptxt, /* [in] Array of strings */
274 INT cStrings /* [in] Number of strings in array */
Peter Ganten87d95b71999-09-19 14:17:14 +0000275 )
276{
277 FIXME("stub!\n");
278 SetLastError ( ERROR_CALL_NOT_IMPLEMENTED );
279 return 0;
280}
281
282
283
284/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000285 * PolyTextOutW (GDI32.@)
286 *
287 * Draw several Strings
Peter Ganten87d95b71999-09-19 14:17:14 +0000288 */
Vincent Béron9a624912002-05-31 23:06:46 +0000289BOOL WINAPI PolyTextOutW (
290 HDC hdc, /* [in] Handle to device context */
Patrik Stridvall2b3aa612000-12-01 23:58:28 +0000291 PPOLYTEXTW pptxt, /* [in] Array of strings */
292 INT cStrings /* [in] Number of strings in array */
Peter Ganten87d95b71999-09-19 14:17:14 +0000293 )
294{
295 FIXME("stub!\n");
296 SetLastError ( ERROR_CALL_NOT_IMPLEMENTED );
297 return 0;
298}