56d0ec0656133d49495a95b43c5c2402e64f5329
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * PROJECT: ReactOS user32.dll
21 * FILE: win32ss/user/user32/windows/font.c
23 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
25 * 09-05-2001 CSH Created
28 /* INCLUDES ******************************************************************/
32 #include <wine/debug.h>
34 WINE_DEFAULT_DEBUG_CHANNEL(text
);
36 DWORD WINAPI
GdiGetCodePage(HDC hdc
);
38 INT WINAPI
DrawTextExWorker( HDC hdc
, LPWSTR str
, INT i_count
,
39 LPRECT rect
, UINT flags
, LPDRAWTEXTPARAMS dtp
);
42 /* FUNCTIONS *****************************************************************/
45 /***********************************************************************
48 * Helper function for TabbedTextOut() and GetTabbedTextExtent().
49 * Note: this doesn't work too well for text-alignment modes other
50 * than TA_LEFT|TA_TOP. But we want bug-for-bug compatibility :-)
52 /* WINE synced 22-May-2006 */
53 LONG
TEXT_TabbedTextOut( HDC hdc
,
72 GetTextMetricsW( hdc
, &tm
);
81 defWidth
= 8 * tm
.tmAveCharWidth
;
90 /* chop the string into substrings of 0 or more <tabs>
91 * possibly followed by 1 or more normal characters */
92 for (i
= 0; i
< count
; i
++)
93 if (lpstr
[i
] != '\t') break;
94 for (j
= i
; j
< count
; j
++)
95 if (lpstr
[j
] == '\t') break;
96 /* get the extent of the normal character part */
97 GetTextExtentPointW( hdc
, lpstr
+ i
, j
- i
, &extent
);
98 /* and if there is a <tab>, calculate its position */
100 /* get x coordinate for the drawing of this string */
101 for (; cTabStops
> i
; lpTabPos
++, cTabStops
--)
103 if( nTabOrg
+ abs( *lpTabPos
) > x
) {
104 if( lpTabPos
[ i
- 1] >= 0) {
105 /* a left aligned tab */
106 x
= nTabOrg
+ lpTabPos
[ i
-1] + extent
.cx
;
111 /* if tab pos is negative then text is right-aligned
112 * to tab stop meaning that the string extends to the
113 * left, so we must subtract the width of the string */
114 if (nTabOrg
- lpTabPos
[ i
- 1] - extent
.cx
> x
)
116 x
= nTabOrg
- lpTabPos
[ i
- 1];
123 /* if we have run out of tab stops and we have a valid default tab
124 * stop width then round x up to that width */
125 if ((cTabStops
<= i
) && (defWidth
> 0)) {
126 x0
= nTabOrg
+ ((x
- nTabOrg
) / defWidth
+ i
) * defWidth
;
128 } else if ((cTabStops
<= i
) && (defWidth
< 0)) {
129 x
= nTabOrg
+ ((x
- nTabOrg
+ extent
.cx
) / -defWidth
+ i
)
140 r
.bottom
= y
+ extent
.cy
;
142 ExtTextOutW( hdc
, x0
, y
, GetBkMode(hdc
) == OPAQUE
? ETO_OPAQUE
: 0,
143 &r
, lpstr
+ i
, j
- i
, NULL
);
150 extent
.cy
= tm
.tmHeight
;
152 return MAKELONG(x
- start
, extent
.cy
);
167 CONST INT
*lpnTabStopPositions
,
173 UINT cp
= GdiGetCodePage( hDC
); // CP_ACP
175 len
= MultiByteToWideChar(cp
, 0, lpString
, nCount
, NULL
, 0);
177 strW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
179 MultiByteToWideChar(cp
, 0, lpString
, nCount
, strW
, len
);
180 ret
= TabbedTextOutW(hDC
, X
, Y
, strW
, len
, nTabPositions
, lpnTabStopPositions
, nTabOrigin
);
181 HeapFree(GetProcessHeap(), 0, strW
);
197 CONST INT
*lpnTabStopPositions
,
200 return TEXT_TabbedTextOut(hDC
, X
, Y
, lpString
, nCount
, nTabPositions
, lpnTabStopPositions
, nTabOrigin
, TRUE
);
203 /* WINE synced 22-May-2006 */
209 GetTabbedTextExtentA(
214 CONST INT
*lpnTabStopPositions
)
217 UINT cp
= GdiGetCodePage( hDC
); // CP_ACP
221 len
= MultiByteToWideChar(cp
, 0, lpString
, nCount
, NULL
, 0);
223 strW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
225 MultiByteToWideChar(cp
, 0, lpString
, nCount
, strW
, len
);
226 ret
= GetTabbedTextExtentW(hDC
, strW
, len
, nTabPositions
, lpnTabStopPositions
);
227 HeapFree(GetProcessHeap(), 0, strW
);
236 GetTabbedTextExtentW(
241 CONST INT
*lpnTabStopPositions
)
243 return TEXT_TabbedTextOut(hDC
, 0, 0, lpString
, nCount
, nTabPositions
, lpnTabStopPositions
, 0, FALSE
);
247 /***********************************************************************
248 * DrawTextExW (USER32.@)
250 * The documentation on the extra space required for DT_MODIFYSTRING at MSDN
251 * is not quite complete, especially with regard to \0. We will assume that
252 * the returned string could have a length of up to i_count+3 and also have
253 * a trailing \0 (which would be 4 more than a not-null-terminated string but
254 * 3 more than a null-terminated string). If this is not so then increase
255 * the allowance in DrawTextExA.
257 #define MAX_BUFFER 1024
261 * Synced with Wine Staging 1.7.37
263 INT WINAPI
DrawTextExW( HDC hdc
, LPWSTR str
, INT i_count
,
264 LPRECT rect
, UINT flags
, LPDRAWTEXTPARAMS dtp
)
266 return DrawTextExWorker( hdc
, str
, i_count
, rect
, flags
, dtp
);
269 /***********************************************************************
270 * DrawTextExA (USER32.@)
272 * If DT_MODIFYSTRING is specified then there must be room for up to
273 * 4 extra characters. We take great care about just how much modified
278 * Synced with Wine Staging 1.7.37
280 INT WINAPI
DrawTextExA( HDC hdc
, LPSTR str
, INT count
,
281 LPRECT rect
, UINT flags
, LPDRAWTEXTPARAMS dtp
)
292 if (!count
) return 0;
293 if (!str
&& count
> 0) return 0;
294 if( !str
|| ((count
== -1) && !(count
= strlen(str
))))
299 if (dtp
&& dtp
->cbSize
!= sizeof(DRAWTEXTPARAMS
))
302 GetTextMetricsA(hdc
, &tm
);
303 if (flags
& DT_EXTERNALLEADING
)
304 lh
= tm
.tmHeight
+ tm
.tmExternalLeading
;
308 if( flags
& DT_CALCRECT
)
310 rect
->right
= rect
->left
;
311 if( flags
& DT_SINGLELINE
)
312 rect
->bottom
= rect
->top
+ lh
;
314 rect
->bottom
= rect
->top
;
318 cp
= GdiGetCodePage( hdc
);
319 wcount
= MultiByteToWideChar( cp
, 0, str
, count
, NULL
, 0 );
322 if (flags
& DT_MODIFYSTRING
)
327 wstr
= HeapAlloc(GetProcessHeap(), 0, wmax
* sizeof(WCHAR
));
330 MultiByteToWideChar( cp
, 0, str
, count
, wstr
, wcount
);
331 if (flags
& DT_MODIFYSTRING
)
332 for (i
=4, p
=wstr
+wcount
; i
--; p
++) *p
=0xFFFE;
333 /* Initialise the extra characters so that we can see which ones
334 * change. U+FFFE is guaranteed to be not a unicode character and
335 * so will not be generated by DrawTextEx itself.
337 ret
= DrawTextExW( hdc
, wstr
, wcount
, rect
, flags
, dtp
);
338 if (flags
& DT_MODIFYSTRING
)
340 /* Unfortunately the returned string may contain multiple \0s
341 * and so we need to measure it ourselves.
343 for (i
=4, p
=wstr
+wcount
; i
-- && *p
!= 0xFFFE; p
++) wcount
++;
344 WideCharToMultiByte( cp
, 0, wstr
, wcount
, str
, amax
, NULL
, NULL
);
346 HeapFree(GetProcessHeap(), 0, wstr
);
351 /***********************************************************************
352 * DrawTextW (USER32.@)
355 * Synced with Wine Staging 1.7.37
357 INT WINAPI
DrawTextW( HDC hdc
, LPCWSTR str
, INT count
, LPRECT rect
, UINT flags
)
361 memset (&dtp
, 0, sizeof(dtp
));
362 dtp
.cbSize
= sizeof(dtp
);
363 if (flags
& DT_TABSTOP
)
365 dtp
.iTabLength
= (flags
>> 8) & 0xff;
368 return DrawTextExW(hdc
, (LPWSTR
)str
, count
, rect
, flags
, &dtp
);
371 /***********************************************************************
372 * DrawTextA (USER32.@)
375 * Synced with Wine Staging 1.7.37
377 INT WINAPI
DrawTextA( HDC hdc
, LPCSTR str
, INT count
, LPRECT rect
, UINT flags
)
381 memset (&dtp
, 0, sizeof(dtp
));
382 dtp
.cbSize
= sizeof(dtp
);
383 if (flags
& DT_TABSTOP
)
385 dtp
.iTabLength
= (flags
>> 8) & 0xff;
388 return DrawTextExA( hdc
, (LPSTR
)str
, count
, rect
, flags
, &dtp
);