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
28 #include "wine/winuser16.h"
32 #include "gdi_private.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(text
);
37 /***********************************************************************
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 (NB, this may be CP_SYMBOL so watch
47 * out). The caller should free the returned LPWSTR from the process
50 LPWSTR
FONT_mbtowc(HDC hdc
, LPCSTR str
, INT count
, INT
*plenW
, UINT
*pCP
)
56 int charset
= GetTextCharset(hdc
);
58 /* Hmm, nicely designed api this one! */
59 if(TranslateCharsetInfo((DWORD
*)charset
, &csi
, TCI_SRCCHARSET
))
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...
89 FIXME("Can't find codepage for charset %d\n", charset
);
94 TRACE("cp == %d\n", cp
);
96 if(count
== -1) count
= strlen(str
);
98 lenW
= MultiByteToWideChar(cp
, 0, str
, count
, NULL
, 0);
99 strW
= HeapAlloc(GetProcessHeap(), 0, (lenW
+ 1) * sizeof(WCHAR
));
100 MultiByteToWideChar(cp
, 0, str
, count
, strW
, lenW
);
103 strW
= HeapAlloc(GetProcessHeap(), 0, (lenW
+ 1) * sizeof(WCHAR
));
104 for(i
= 0; i
< count
; i
++) strW
[i
] = (BYTE
)str
[i
];
107 TRACE("mapped %s -> %s\n", debugstr_an(str
, count
), debugstr_wn(strW
, lenW
));
108 if(plenW
) *plenW
= lenW
;
114 /***********************************************************************
115 * ExtTextOutA (GDI32.@)
117 BOOL WINAPI
ExtTextOutA( HDC hdc
, INT x
, INT y
, UINT flags
,
118 const RECT
*lprect
, LPCSTR str
, UINT count
, const INT
*lpDx
)
122 LPWSTR p
= FONT_mbtowc(hdc
, str
, count
, &wlen
, &codepage
);
127 unsigned int i
= 0, j
= 0;
129 lpDxW
= (LPINT
)HeapAlloc( GetProcessHeap(), 0, wlen
*sizeof(INT
));
131 if(IsDBCSLeadByteEx(codepage
, str
[i
])) {
132 lpDxW
[j
++] = lpDx
[i
] + lpDx
[i
+1];
135 lpDxW
[j
++] = lpDx
[i
];
141 ret
= ExtTextOutW( hdc
, x
, y
, flags
, lprect
, p
, wlen
, lpDxW
);
143 HeapFree( GetProcessHeap(), 0, p
);
144 if (lpDxW
) HeapFree( GetProcessHeap(), 0, lpDxW
);
149 /***********************************************************************
150 * ExtTextOutW (GDI32.@)
152 BOOL WINAPI
ExtTextOutW( HDC hdc
, INT x
, INT y
, UINT flags
,
153 const RECT
*lprect
, LPCWSTR str
, UINT count
, const INT
*lpDx
)
156 DC
* dc
= DC_GetDCUpdate( hdc
);
159 if(PATH_IsPathOpen(dc
->path
))
160 FIXME("called on an open path\n");
161 else if(dc
->funcs
->pExtTextOut
)
163 if( !(flags
&(ETO_GLYPH_INDEX
|ETO_IGNORELANGUAGE
)) && BidiAvail
&& count
>0 )
165 /* The caller did not specify that language processing was already done.
167 LPWSTR lpReorderedString
=HeapAlloc(GetProcessHeap(), 0, count
*sizeof(WCHAR
));
169 BIDI_Reorder( str
, count
, GCP_REORDER
,
170 ((flags
&ETO_RTLREADING
)!=0 || (GetTextAlign(hdc
)&TA_RTLREADING
)!=0)?
171 WINE_GCPW_FORCE_RTL
:WINE_GCPW_FORCE_LTR
,
172 lpReorderedString
, count
, NULL
);
174 ret
= dc
->funcs
->pExtTextOut(dc
->physDev
,x
,y
,flags
|ETO_IGNORELANGUAGE
,
175 lprect
,lpReorderedString
,count
,lpDx
);
176 HeapFree(GetProcessHeap(), 0, lpReorderedString
);
178 ret
= dc
->funcs
->pExtTextOut(dc
->physDev
,x
,y
,flags
,lprect
,str
,count
,lpDx
);
180 GDI_ReleaseObj( hdc
);
186 /***********************************************************************
189 BOOL WINAPI
TextOutA( HDC hdc
, INT x
, INT y
, LPCSTR str
, INT count
)
191 return ExtTextOutA( hdc
, x
, y
, 0, NULL
, str
, count
, NULL
);
195 /***********************************************************************
198 BOOL WINAPI
TextOutW(HDC hdc
, INT x
, INT y
, LPCWSTR str
, INT count
)
200 return ExtTextOutW( hdc
, x
, y
, 0, NULL
, str
, count
, NULL
);
204 /***********************************************************************
205 * PolyTextOutA (GDI32.@)
207 * Draw several Strings
209 BOOL WINAPI
PolyTextOutA (
210 HDC hdc
, /* [in] Handle to device context */
211 PPOLYTEXTA pptxt
, /* [in] Array of strings */
212 INT cStrings
/* [in] Number of strings in array */
215 for (; cStrings
>0; cStrings
--, pptxt
++)
216 if (!ExtTextOutA( hdc
, pptxt
->x
, pptxt
->y
, pptxt
->uiFlags
, &pptxt
->rcl
, pptxt
->lpstr
, pptxt
->n
, pptxt
->pdx
))
223 /***********************************************************************
224 * PolyTextOutW (GDI32.@)
226 * Draw several Strings
228 BOOL WINAPI
PolyTextOutW (
229 HDC hdc
, /* [in] Handle to device context */
230 PPOLYTEXTW pptxt
, /* [in] Array of strings */
231 INT cStrings
/* [in] Number of strings in array */
234 for (; cStrings
>0; cStrings
--, pptxt
++)
235 if (!ExtTextOutW( hdc
, pptxt
->x
, pptxt
->y
, pptxt
->uiFlags
, &pptxt
->rcl
, pptxt
->lpstr
, pptxt
->n
, pptxt
->pdx
))