1 | /* $Id: text.cpp,v 1.12 2001-05-27 19:01:35 sandervl Exp $ */
|
---|
2 |
|
---|
3 | /*
|
---|
4 | * Font and Text Functions
|
---|
5 | *
|
---|
6 | * Copyright 1999 Christoph Bratschi
|
---|
7 | *
|
---|
8 | * Copyright 1993, 1994 Alexandre Julliard
|
---|
9 | *
|
---|
10 | * Project Odin Software License can be found in LICENSE.TXT
|
---|
11 | */
|
---|
12 |
|
---|
13 | #include "winuser.h"
|
---|
14 | #include "user32.h"
|
---|
15 | #include "syscolor.h"
|
---|
16 | #include <winnls.h>
|
---|
17 |
|
---|
18 | #define DBG_LOCALLOG DBG_text
|
---|
19 | #include "dbglocal.h"
|
---|
20 |
|
---|
21 | //WINE parts: wine-991031
|
---|
22 |
|
---|
23 | INT WIN32API DrawTextA(HDC hDC,LPCSTR lpString,INT nCount,PRECT lpRect,UINT nFormat)
|
---|
24 | {
|
---|
25 | dprintf(("USER32: DrawTextA %x %s %d (%d,%d)(%d,%d) %x",hDC, lpString, nCount, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, nFormat));
|
---|
26 |
|
---|
27 | return InternalDrawTextExA(hDC,lpString,nCount,lpRect,nFormat,NULL,FALSE);
|
---|
28 | }
|
---|
29 | //******************************************************************************
|
---|
30 | //******************************************************************************
|
---|
31 | INT WIN32API DrawTextW(HDC hDC,LPCWSTR lpString,INT nCount,PRECT lpRect,UINT nFormat)
|
---|
32 | {
|
---|
33 | dprintf(("USER32: DrawTextA %x %ls %d (%d,%d)(%d,%d) %x",hDC, lpString, nCount, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, nFormat));
|
---|
34 |
|
---|
35 | return InternalDrawTextExW(hDC,lpString,nCount,lpRect,nFormat,NULL,FALSE);
|
---|
36 | }
|
---|
37 | //******************************************************************************
|
---|
38 | //******************************************************************************
|
---|
39 | INT WIN32API DrawTextExA(HDC hdc,LPCSTR lpchText,INT cchText,LPRECT lprc,UINT dwDTFormat,LPDRAWTEXTPARAMS lpDTParams)
|
---|
40 | {
|
---|
41 | dprintf(("USER32: DrawTextExA %x %s %d (%d,%d)(%d,%d) %x",hdc, lpchText, cchText, lprc->left, lprc->top, lprc->right, lprc->bottom, dwDTFormat));
|
---|
42 |
|
---|
43 | return InternalDrawTextExA(hdc,lpchText,cchText,lprc,dwDTFormat,lpDTParams,TRUE);
|
---|
44 | }
|
---|
45 | //******************************************************************************
|
---|
46 | //******************************************************************************
|
---|
47 | int WIN32API DrawTextExW(HDC hdc,LPWSTR lpchText,INT cchText,LPRECT lprc,UINT dwDTFormat,LPDRAWTEXTPARAMS lpDTParams)
|
---|
48 | {
|
---|
49 | dprintf(("USER32: DrawTextExA %x %ls %d (%d,%d)(%d,%d) %x",hdc, lpchText, cchText, lprc->left, lprc->top, lprc->right, lprc->bottom, dwDTFormat));
|
---|
50 |
|
---|
51 | return InternalDrawTextExW(hdc,lpchText,cchText,lprc,dwDTFormat,lpDTParams,TRUE);
|
---|
52 | }
|
---|
53 | #if 1
|
---|
54 | //Based on Wine version 20010510
|
---|
55 | /***********************************************************************
|
---|
56 | * TEXT_TabbedTextOut
|
---|
57 | *
|
---|
58 | * Helper function for TabbedTextOut() and GetTabbedTextExtent().
|
---|
59 | * Note: this doesn't work too well for text-alignment modes other
|
---|
60 | * than TA_LEFT|TA_TOP. But we want bug-for-bug compatibility :-)
|
---|
61 | */
|
---|
62 | static LONG TEXT_TabbedTextOut( HDC hdc, INT x, INT y, LPCSTR lpstr,
|
---|
63 | INT count, INT cTabStops, const INT16 *lpTabPos16,
|
---|
64 | const INT *lpTabPos32, INT nTabOrg,
|
---|
65 | BOOL fDisplayText )
|
---|
66 | {
|
---|
67 | INT defWidth;
|
---|
68 | SIZE extent;
|
---|
69 | int i, tabPos = x;
|
---|
70 | int start = x;
|
---|
71 |
|
---|
72 | extent.cx = 0;
|
---|
73 | extent.cy = 0;
|
---|
74 |
|
---|
75 | if (cTabStops == 1)
|
---|
76 | {
|
---|
77 | defWidth = lpTabPos32 ? *lpTabPos32 : *lpTabPos16;
|
---|
78 | cTabStops = 0;
|
---|
79 | }
|
---|
80 | else
|
---|
81 | {
|
---|
82 | TEXTMETRICA tm;
|
---|
83 | GetTextMetricsA( hdc, &tm );
|
---|
84 | defWidth = 8 * tm.tmAveCharWidth;
|
---|
85 | }
|
---|
86 |
|
---|
87 | while (count > 0)
|
---|
88 | {
|
---|
89 | for (i = 0; i < count; i++)
|
---|
90 | if (lpstr[i] == '\t') break;
|
---|
91 | GetTextExtentPointA( hdc, lpstr, i, &extent );
|
---|
92 | if (lpTabPos32)
|
---|
93 | {
|
---|
94 | while ((cTabStops > 0) &&
|
---|
95 | (nTabOrg + *lpTabPos32 <= x + extent.cx))
|
---|
96 | {
|
---|
97 | lpTabPos32++;
|
---|
98 | cTabStops--;
|
---|
99 | }
|
---|
100 | }
|
---|
101 | else
|
---|
102 | {
|
---|
103 | while ((cTabStops > 0) &&
|
---|
104 | (nTabOrg + *lpTabPos16 <= x + extent.cx))
|
---|
105 | {
|
---|
106 | lpTabPos16++;
|
---|
107 | cTabStops--;
|
---|
108 | }
|
---|
109 | }
|
---|
110 | if (i == count)
|
---|
111 | tabPos = x + extent.cx;
|
---|
112 | else if (cTabStops > 0)
|
---|
113 | tabPos = nTabOrg + (lpTabPos32 ? *lpTabPos32 : *lpTabPos16);
|
---|
114 | else
|
---|
115 | tabPos = nTabOrg + ((x + extent.cx - nTabOrg) / defWidth + 1) * defWidth;
|
---|
116 | if (fDisplayText)
|
---|
117 | {
|
---|
118 | RECT r;
|
---|
119 | r.left = x;
|
---|
120 | r.top = y;
|
---|
121 | r.right = tabPos;
|
---|
122 | r.bottom = y + extent.cy;
|
---|
123 | ExtTextOutA( hdc, x, y,
|
---|
124 | GetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0,
|
---|
125 | &r, lpstr, i, NULL );
|
---|
126 | }
|
---|
127 | x = tabPos;
|
---|
128 | count -= i+1;
|
---|
129 | lpstr += i+1;
|
---|
130 | }
|
---|
131 | return MAKELONG(tabPos - start, extent.cy);
|
---|
132 | }
|
---|
133 |
|
---|
134 |
|
---|
135 |
|
---|
136 | /***********************************************************************
|
---|
137 | * TabbedTextOutA (USER32.@)
|
---|
138 | */
|
---|
139 | LONG WINAPI TabbedTextOutA( HDC hdc, INT x, INT y, LPCSTR lpstr, INT count,
|
---|
140 | INT cTabStops, INT *lpTabPos, INT nTabOrg )
|
---|
141 | {
|
---|
142 | dprintf(("USER32: TabbedTextOutA %x (%d,%d) %s %d %d %x %d", hdc, x, y, lpstr, count, cTabStops, lpTabPos, nTabOrg));
|
---|
143 | return TEXT_TabbedTextOut( hdc, x, y, lpstr, count, cTabStops,
|
---|
144 | NULL, lpTabPos, nTabOrg, TRUE );
|
---|
145 | }
|
---|
146 |
|
---|
147 |
|
---|
148 | /***********************************************************************
|
---|
149 | * TabbedTextOutW (USER32.@)
|
---|
150 | */
|
---|
151 | LONG WINAPI TabbedTextOutW( HDC hdc, INT x, INT y, LPCWSTR str, INT count,
|
---|
152 | INT cTabStops, INT *lpTabPos, INT nTabOrg )
|
---|
153 | {
|
---|
154 | LONG ret;
|
---|
155 | LPSTR p;
|
---|
156 | INT acount;
|
---|
157 | UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
|
---|
158 |
|
---|
159 | acount = WideCharToMultiByte(codepage,0,str,count,NULL,0,NULL,NULL);
|
---|
160 | p = (LPSTR)HeapAlloc( GetProcessHeap(), 0, acount );
|
---|
161 | if(p == NULL) return 0; /* FIXME: is this the correct return on failure */
|
---|
162 | acount = WideCharToMultiByte(codepage,0,str,count,p,acount,NULL,NULL);
|
---|
163 | ret = TabbedTextOutA( hdc, x, y, p, acount, cTabStops, lpTabPos, nTabOrg );
|
---|
164 | HeapFree( GetProcessHeap(), 0, p );
|
---|
165 | return ret;
|
---|
166 | }
|
---|
167 |
|
---|
168 |
|
---|
169 |
|
---|
170 | /***********************************************************************
|
---|
171 | * GetTabbedTextExtentA (USER32.@)
|
---|
172 | */
|
---|
173 | DWORD WINAPI GetTabbedTextExtentA( HDC hdc, LPCSTR lpstr, INT count,
|
---|
174 | INT cTabStops, INT *lpTabPos )
|
---|
175 | {
|
---|
176 | dprintf(("USER32: GetTabbedTextExtentA %x %s %d %d %x",hdc, lpstr, count, cTabStops, lpTabPos));
|
---|
177 |
|
---|
178 | return TEXT_TabbedTextOut( hdc, 0, 0, lpstr, count, cTabStops,
|
---|
179 | NULL, lpTabPos, 0, FALSE );
|
---|
180 | }
|
---|
181 |
|
---|
182 |
|
---|
183 | /***********************************************************************
|
---|
184 | * GetTabbedTextExtentW (USER32.@)
|
---|
185 | */
|
---|
186 | DWORD WINAPI GetTabbedTextExtentW( HDC hdc, LPCWSTR lpstr, INT count,
|
---|
187 | INT cTabStops, INT *lpTabPos )
|
---|
188 | {
|
---|
189 | LONG ret;
|
---|
190 | LPSTR p;
|
---|
191 | INT acount;
|
---|
192 | UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
|
---|
193 |
|
---|
194 | acount = WideCharToMultiByte(codepage,0,lpstr,count,NULL,0,NULL,NULL);
|
---|
195 | p = (LPSTR)HeapAlloc( GetProcessHeap(), 0, acount );
|
---|
196 | if(p == NULL) return 0; /* FIXME: is this the correct failure value? */
|
---|
197 | acount = WideCharToMultiByte(codepage,0,lpstr,count,p,acount,NULL,NULL);
|
---|
198 | ret = GetTabbedTextExtentA( hdc, p, acount, cTabStops, lpTabPos );
|
---|
199 | HeapFree( GetProcessHeap(), 0, p );
|
---|
200 | return ret;
|
---|
201 | }
|
---|
202 | #else
|
---|
203 | //******************************************************************************
|
---|
204 | //******************************************************************************
|
---|
205 | DWORD WIN32API GetTabbedTextExtentA( HDC hDC, LPCSTR lpString, int nCount, int nTabPositions, LPINT lpnTabStopPositions)
|
---|
206 | {
|
---|
207 | dprintf(("USER32: GetTabbedTextExtentA %x",hDC));
|
---|
208 |
|
---|
209 | return InternalGetTabbedTextExtentA(hDC,lpString,nCount,nTabPositions,lpnTabStopPositions);
|
---|
210 | }
|
---|
211 | //******************************************************************************
|
---|
212 | //******************************************************************************
|
---|
213 | DWORD WIN32API GetTabbedTextExtentW(HDC hDC,LPCWSTR lpString,INT nCount,INT nTabPositions,LPINT lpnTabStopPositions)
|
---|
214 | {
|
---|
215 | dprintf(("USER32: GetTabbedTextExtentW %x",hDC));
|
---|
216 |
|
---|
217 | return InternalGetTabbedTextExtentW(hDC,lpString,nCount,nTabPositions,lpnTabStopPositions);
|
---|
218 | }
|
---|
219 | //******************************************************************************
|
---|
220 | //******************************************************************************
|
---|
221 | LONG WIN32API TabbedTextOutA(HDC hdc,INT x,INT y,LPCSTR lpString,INT nCount,INT nTabPositions, LPINT lpnTabStopPositions,INT nTabOrigin)
|
---|
222 | {
|
---|
223 | dprintf(("USER32: TabbedTextOutA %x",hdc));
|
---|
224 |
|
---|
225 | return InternalTabbedTextOutA(hdc,x,y,lpString,nCount,nTabPositions,lpnTabStopPositions,nTabOrigin);
|
---|
226 | }
|
---|
227 | //******************************************************************************
|
---|
228 | //******************************************************************************
|
---|
229 | LONG WIN32API TabbedTextOutW( HDC hdc, int x, int y, LPCWSTR lpString, int nCount, int nTabPositions, LPINT lpnTabStopPositions, int nTabOrigin)
|
---|
230 | {
|
---|
231 | dprintf(("USER32: TabbedTextOutW %x",hdc));
|
---|
232 |
|
---|
233 | return InternalTabbedTextOutW(hdc,x,y,lpString,nCount,nTabPositions,lpnTabStopPositions,nTabOrigin);
|
---|
234 | }
|
---|
235 | #endif
|
---|
236 | //******************************************************************************
|
---|
237 | // WINE/objects/text.c
|
---|
238 | //******************************************************************************
|
---|
239 | static BOOL InternalGrayString(HDC hdc,HBRUSH hBrush,GRAYSTRINGPROC lpOutputFunc,LPARAM lpData,INT nCount,INT x,INT y,INT nWidth,INT nHeight,BOOL isUnicode)
|
---|
240 | {
|
---|
241 | HBITMAP hbm, hbmsave;
|
---|
242 | HBRUSH hbsave;
|
---|
243 | HFONT hfsave;
|
---|
244 | HDC memdc = CreateCompatibleDC(hdc);
|
---|
245 | BOOL retval = TRUE;
|
---|
246 | RECT r;
|
---|
247 | COLORREF fg, bg;
|
---|
248 |
|
---|
249 | if (!hdc) return FALSE;
|
---|
250 |
|
---|
251 | if (nCount == 0)
|
---|
252 | nCount = isUnicode ? lstrlenW((LPCWSTR)lpData):lstrlenA((LPCSTR)lpData);
|
---|
253 |
|
---|
254 | if((nWidth == 0 || nHeight == 0) && nCount != -1)
|
---|
255 | {
|
---|
256 | SIZE s;
|
---|
257 |
|
---|
258 | if (isUnicode)
|
---|
259 | GetTextExtentPoint32W(hdc,(LPCWSTR)lpData,nCount,&s);
|
---|
260 | else
|
---|
261 | GetTextExtentPoint32A(hdc,(LPCSTR)lpData,nCount,&s);
|
---|
262 | if (nWidth == 0) nWidth = s.cx;
|
---|
263 | if (nHeight == 0) nHeight = s.cy;
|
---|
264 | }
|
---|
265 |
|
---|
266 | r.left = r.top = 0;
|
---|
267 | r.right = nWidth;
|
---|
268 | r.bottom = nHeight;
|
---|
269 |
|
---|
270 | hbm = CreateBitmap(nWidth,nHeight,1,1,NULL);
|
---|
271 | hbmsave = (HBITMAP)SelectObject(memdc,hbm);
|
---|
272 | FillRect(memdc,&r,(HBRUSH)GetStockObject(BLACK_BRUSH));
|
---|
273 | SetTextColor(memdc,RGB(255,255,255));
|
---|
274 | SetBkColor(memdc,RGB(0,0,0));
|
---|
275 | hfsave = (HFONT)SelectObject(memdc,GetCurrentObject(hdc,OBJ_FONT));
|
---|
276 |
|
---|
277 | if (lpOutputFunc)
|
---|
278 | retval = lpOutputFunc(memdc,lpData,nCount);
|
---|
279 | else
|
---|
280 | if (isUnicode)
|
---|
281 | TextOutW(memdc,0,0,(LPCWSTR)lpData,nCount);
|
---|
282 | else
|
---|
283 | TextOutA(memdc,0,0,(LPCSTR)lpData,nCount);
|
---|
284 | SelectObject(memdc, hfsave);
|
---|
285 |
|
---|
286 | /*
|
---|
287 | * Windows doc says that the bitmap isn't grayed when len == -1 and
|
---|
288 | * the callback function returns FALSE. However, testing this on
|
---|
289 | * win95 showed otherwise...
|
---|
290 | */
|
---|
291 | #ifdef GRAYSTRING_USING_DOCUMENTED_BEHAVIOUR
|
---|
292 | if(retval || nCount != -1)
|
---|
293 | #endif
|
---|
294 | {
|
---|
295 | hbsave = (HBRUSH)SelectObject(memdc,GetPattern55AABrush());
|
---|
296 | PatBlt(memdc,0,0,nWidth,nHeight,0x000A0329);
|
---|
297 | SelectObject(memdc, hbsave);
|
---|
298 | }
|
---|
299 |
|
---|
300 | if (hBrush) hbsave = (HBRUSH)SelectObject(hdc,hBrush);
|
---|
301 | fg = SetTextColor(hdc, RGB(0, 0, 0));
|
---|
302 | bg = SetBkColor(hdc, RGB(255, 255, 255));
|
---|
303 | BitBlt(hdc,x,y,nWidth,nHeight,memdc,0,0,0x00E20746);
|
---|
304 | SetTextColor(hdc, fg);
|
---|
305 | SetBkColor(hdc, bg);
|
---|
306 | if (hBrush) SelectObject(hdc,hbsave);
|
---|
307 |
|
---|
308 | SelectObject(memdc, hbmsave);
|
---|
309 | DeleteObject(hbm);
|
---|
310 | DeleteDC(memdc);
|
---|
311 |
|
---|
312 | return retval;
|
---|
313 | }
|
---|
314 | //******************************************************************************
|
---|
315 | //******************************************************************************
|
---|
316 | BOOL WIN32API GrayStringA(HDC hdc,HBRUSH hBrush,GRAYSTRINGPROC lpOutputFunc,LPARAM lpData,int nCount,int X,int Y,int nWidth,int nHeight)
|
---|
317 | {
|
---|
318 | dprintf(("USER32: GrayStringA %x",hdc));
|
---|
319 |
|
---|
320 | return InternalGrayString(hdc,hBrush,lpOutputFunc,lpData,nCount,X,Y,nWidth,nHeight,FALSE);
|
---|
321 | }
|
---|
322 | //******************************************************************************
|
---|
323 | //******************************************************************************
|
---|
324 | BOOL WIN32API GrayStringW(HDC hdc,HBRUSH hBrush,GRAYSTRINGPROC lpOutputFunc,LPARAM lpData,int nCount,int X,int Y,int nWidth,int nHeight)
|
---|
325 | {
|
---|
326 | dprintf(("USER32: GrayStringW %x",hdc));
|
---|
327 |
|
---|
328 | return InternalGrayString(hdc,hBrush,lpOutputFunc,lpData,nCount,X,Y,nWidth,nHeight,TRUE);
|
---|
329 | }
|
---|
330 |
|
---|