Fix the MHz detection code.
[wine/multimedia.git] / objects / text.c
blobdfc239e029fee5fce79feb0c8e9c21d4510c2360
1 /*
2 * text functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 * Copyright 2003 Shachar Shemesh
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.
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.
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
22 #include <string.h>
24 #include "windef.h"
25 #include "wingdi.h"
26 #include "wine/winuser16.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "gdi.h"
30 #include "wine/debug.h"
31 #include "winnls.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(text);
35 /***********************************************************************
36 * FONT_mbtowc
38 * Returns a '\0' terminated Unicode translation of str using the
39 * charset of the currently selected font in hdc. If count is -1 then
40 * str is assumed to be '\0' terminated, otherwise it contains the
41 * number of bytes to convert. If plenW is non-NULL, on return it
42 * will point to the number of WCHARs (excluding the '\0') that have
43 * been written. If pCP is non-NULL, on return it will point to the
44 * codepage used in the conversion (NB, this may be CP_SYMBOL so watch
45 * out). The caller should free the returned LPWSTR from the process
46 * heap itself.
48 LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
50 UINT cp = CP_ACP;
51 INT lenW, i;
52 LPWSTR strW;
53 CHARSETINFO csi;
54 int charset = GetTextCharset(hdc);
56 /* Hmm, nicely designed api this one! */
57 if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET))
58 cp = csi.ciACP;
59 else {
60 switch(charset) {
61 case OEM_CHARSET:
62 cp = GetOEMCP();
63 break;
64 case DEFAULT_CHARSET:
65 cp = GetACP();
66 break;
68 case VISCII_CHARSET:
69 case TCVN_CHARSET:
70 case KOI8_CHARSET:
71 case ISO3_CHARSET:
72 case ISO4_CHARSET:
73 case ISO10_CHARSET:
74 case CELTIC_CHARSET:
75 /* FIXME: These have no place here, but because x11drv
76 enumerates fonts with these (made up) charsets some apps
77 might use them and then the FIXME below would become
78 annoying. Now we could pick the intended codepage for
79 each of these, but since it's broken anyway we'll just
80 use CP_ACP and hope it'll go away...
82 cp = CP_ACP;
83 break;
86 default:
87 FIXME("Can't find codepage for charset %d\n", charset);
88 break;
92 TRACE("cp == %d\n", cp);
94 if(count == -1) count = strlen(str);
95 if(cp != CP_SYMBOL) {
96 lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
97 strW = HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
98 MultiByteToWideChar(cp, 0, str, count, strW, lenW);
99 } else {
100 lenW = count;
101 strW = HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
102 for(i = 0; i < count; i++) strW[i] = (BYTE)str[i];
104 strW[lenW] = '\0';
105 TRACE("mapped %s -> %s\n", debugstr_an(str, count), debugstr_wn(strW, lenW));
106 if(plenW) *plenW = lenW;
107 if(pCP) *pCP = cp;
108 return strW;
112 /***********************************************************************
113 * ExtTextOutA (GDI32.@)
115 BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
116 const RECT *lprect, LPCSTR str, UINT count, const INT *lpDx )
118 INT wlen;
119 UINT codepage;
120 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
121 BOOL ret;
122 LPINT lpDxW = NULL;
124 if (lpDx) {
125 unsigned int i = 0, j = 0;
127 lpDxW = (LPINT)HeapAlloc( GetProcessHeap(), 0, wlen*sizeof(INT));
128 while(i < count) {
129 if(IsDBCSLeadByteEx(codepage, str[i])) {
130 lpDxW[j++] = lpDx[i] + lpDx[i+1];
131 i = i + 2;
132 } else {
133 lpDxW[j++] = lpDx[i];
134 i = i + 1;
139 ret = ExtTextOutW( hdc, x, y, flags, lprect, p, wlen, lpDxW );
141 HeapFree( GetProcessHeap(), 0, p );
142 if (lpDxW) HeapFree( GetProcessHeap(), 0, lpDxW );
143 return ret;
147 /***********************************************************************
148 * ExtTextOutW (GDI32.@)
150 BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
151 const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
153 BOOL ret = FALSE;
154 DC * dc = DC_GetDCUpdate( hdc );
155 if (dc)
157 if(PATH_IsPathOpen(dc->path))
158 FIXME("called on an open path\n");
159 else if(dc->funcs->pExtTextOut)
161 if( !(flags&(ETO_GLYPH_INDEX|ETO_IGNORELANGUAGE)) && BidiAvail && count>0 )
163 /* The caller did not specify that language processing was already done.
165 LPWSTR lpReorderedString=HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
167 BIDI_Reorder( str, count, GCP_REORDER,
168 ((flags&ETO_RTLREADING)!=0 || (GetTextAlign(hdc)&TA_RTLREADING)!=0)?
169 WINE_GCPW_FORCE_RTL:WINE_GCPW_FORCE_LTR,
170 lpReorderedString, count, NULL );
172 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags|ETO_IGNORELANGUAGE,
173 lprect,lpReorderedString,count,lpDx);
174 HeapFree(GetProcessHeap(), 0, lpReorderedString);
175 } else
176 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags,lprect,str,count,lpDx);
178 GDI_ReleaseObj( hdc );
180 return ret;
184 /***********************************************************************
185 * TextOutA (GDI32.@)
187 BOOL WINAPI TextOutA( HDC hdc, INT x, INT y, LPCSTR str, INT count )
189 return ExtTextOutA( hdc, x, y, 0, NULL, str, count, NULL );
193 /***********************************************************************
194 * TextOutW (GDI32.@)
196 BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count)
198 return ExtTextOutW( hdc, x, y, 0, NULL, str, count, NULL );
202 /***********************************************************************
203 * PolyTextOutA (GDI32.@)
205 * Draw several Strings
207 BOOL WINAPI PolyTextOutA (
208 HDC hdc, /* [in] Handle to device context */
209 PPOLYTEXTA pptxt, /* [in] Array of strings */
210 INT cStrings /* [in] Number of strings in array */
213 for (; cStrings>0; cStrings--, pptxt++)
214 if (!ExtTextOutA( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
215 return FALSE;
216 return TRUE;
221 /***********************************************************************
222 * PolyTextOutW (GDI32.@)
224 * Draw several Strings
226 BOOL WINAPI PolyTextOutW (
227 HDC hdc, /* [in] Handle to device context */
228 PPOLYTEXTW pptxt, /* [in] Array of strings */
229 INT cStrings /* [in] Number of strings in array */
232 for (; cStrings>0; cStrings--, pptxt++)
233 if (!ExtTextOutW( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
234 return FALSE;
235 return TRUE;