Fixed a reference counting bug I introduced.
[wine/wine-kai.git] / objects / text.c
blob3768bea3d35b77ff684f47b077e9bdbfac7294ae
1 /*
2 * text functions
4 * Copyright 1993, 1994 Alexandre Julliard
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.
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.
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
21 #include <string.h>
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"
32 WINE_DEFAULT_DEBUG_CHANNEL(text);
34 /***********************************************************************
35 * FONT_mbtowc
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.
47 LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
49 UINT cp = CP_ACP;
50 INT lenW, i;
51 LPWSTR strW;
52 CHARSETINFO csi;
53 int charset = GetTextCharset(hdc);
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;
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...
81 cp = CP_ACP;
82 break;
85 default:
86 FIXME("Can't find codepage for charset %d\n", charset);
87 break;
91 TRACE("cp == %d\n", cp);
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];
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;
111 /***********************************************************************
112 * ExtTextOutA (GDI32.@)
114 BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
115 const RECT *lprect, LPCSTR str, UINT count, const INT *lpDx )
117 INT wlen;
118 UINT codepage;
119 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
120 BOOL ret;
121 LPINT lpDxW = NULL;
123 if (lpDx) {
124 unsigned int i = 0, j = 0;
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;
138 ret = ExtTextOutW( hdc, x, y, flags, lprect, p, wlen, lpDxW );
140 HeapFree( GetProcessHeap(), 0, p );
141 if (lpDxW) HeapFree( GetProcessHeap(), 0, lpDxW );
142 return ret;
146 /***********************************************************************
147 * ExtTextOutW (GDI32.@)
149 BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
150 const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
152 BOOL ret = FALSE;
153 DC * dc = DC_GetDCUpdate( hdc );
154 if (dc)
156 if(PATH_IsPathOpen(dc->path))
157 FIXME("called on an open path\n");
158 else if(dc->funcs->pExtTextOut)
160 if( !(flags&(ETO_GLYPH_INDEX|ETO_IGNORELANGUAGE)) )
162 /* The caller did not specify that language processing was already done,
163 * and the font idetifies iteself as requiring language processing.
165 GCP_RESULTSW gcp;
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;
177 GetCharacterPlacementW(hdc, str, count, 0, &gcp, GCP_REORDER );
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);
185 GDI_ReleaseObj( hdc );
187 return ret;
191 /***********************************************************************
192 * TextOutA (GDI32.@)
194 BOOL WINAPI TextOutA( HDC hdc, INT x, INT y, LPCSTR str, INT count )
196 return ExtTextOutA( hdc, x, y, 0, NULL, str, count, NULL );
200 /***********************************************************************
201 * TextOutW (GDI32.@)
203 BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count)
205 return ExtTextOutW( hdc, x, y, 0, NULL, str, count, NULL );
209 /***********************************************************************
210 * GetTextCharset [GDI32.@] Gets character set for font in DC
212 * NOTES
213 * Should it return a UINT32 instead of an INT32?
214 * => YES, as GetTextCharsetInfo returns UINT32
216 * RETURNS
217 * Success: Character set identifier
218 * Failure: DEFAULT_CHARSET
220 UINT WINAPI GetTextCharset(
221 HDC hdc) /* [in] Handle to device context */
223 /* MSDN docs say this is equivalent */
224 return GetTextCharsetInfo(hdc, NULL, 0);
228 /***********************************************************************
229 * GetTextCharsetInfo [GDI32.@] Gets character set for font
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
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(...),...)
240 * RETURNS
241 * Success: Character set identifier
242 * Failure: DEFAULT_CHARSET
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 */
249 UINT charSet = DEFAULT_CHARSET;
250 CHARSETINFO csinfo;
251 TEXTMETRICW tm;
253 if(!GetTextMetricsW(hdc, &tm)) return DEFAULT_CHARSET;
254 charSet = tm.tmCharSet;
256 if (fs != NULL) {
257 if (!TranslateCharsetInfo((LPDWORD)charSet, &csinfo, TCI_SRCCHARSET))
258 return DEFAULT_CHARSET;
259 memcpy(fs, &csinfo.fs, sizeof(FONTSIGNATURE));
261 return charSet;
264 /***********************************************************************
265 * PolyTextOutA (GDI32.@)
267 * Draw several Strings
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 */
275 for (; cStrings>0; cStrings--, pptxt++)
276 if (!ExtTextOutA( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
277 return FALSE;
278 return TRUE;
283 /***********************************************************************
284 * PolyTextOutW (GDI32.@)
286 * Draw several Strings
288 BOOL WINAPI PolyTextOutW (
289 HDC hdc, /* [in] Handle to device context */
290 PPOLYTEXTW pptxt, /* [in] Array of strings */
291 INT cStrings /* [in] Number of strings in array */
294 for (; cStrings>0; cStrings--, pptxt++)
295 if (!ExtTextOutW( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
296 return FALSE;
297 return TRUE;