ReactOS 0.4.15-dev-7842-g558ab78
text.c File Reference
#include <user32.h>
#include <wine/debug.h>
Include dependency graph for text.c:

Go to the source code of this file.

Classes

struct  tag_ellipsis_data
 

Macros

#define assert(e)   ((e) ? (void)0 : _font_assert(#e, __FILE__, __LINE__))
 
#define TAB   9
 
#define LF   10
 
#define CR   13
 
#define SPACE   32
 
#define PREFIX   38
 
#define ALPHA_PREFIX   30 /* Win16: Alphabet prefix */
 
#define KANA_PREFIX   31 /* Win16: Katakana prefix */
 
#define FORWARD_SLASH   '/'
 
#define BACK_SLASH   '\\'
 
#define MAX_BUFFER   1024
 

Typedefs

typedef struct tag_ellipsis_data ellipsis_data
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (text)
 
void _font_assert (const char *msg, const char *file, int line)
 
static void TEXT_Ellipsify (HDC hdc, WCHAR *str, unsigned int max_len, unsigned int *len_str, int width, SIZE *size, WCHAR *modstr, int *len_before, int *len_ellip)
 
static void TEXT_PathEllipsify (HDC hdc, WCHAR *str, unsigned int max_len, unsigned int *len_str, int width, SIZE *size, WCHAR *modstr, ellipsis_data *pellip)
 
FORCEINLINE BOOL IsCJKT (WCHAR wch)
 
static void TEXT_WordBreak (HDC hdc, WCHAR *str, unsigned int max_str, unsigned int *len_str, int width, int format, unsigned int chars_fit, unsigned int *chars_used, SIZE *size)
 
static void TEXT_SkipChars (int *new_count, const WCHAR **new_str, int start_count, const WCHAR *start_str, int max, int n, int prefix)
 
static int TEXT_Reprefix (const WCHAR *str, unsigned int ns, const ellipsis_data *pe)
 
static int remainder_is_none_or_newline (int num_chars, const WCHAR *str)
 
static const WCHARTEXT_NextLineW (HDC hdc, const WCHAR *str, int *count, WCHAR *dest, int *len, int width, DWORD format, SIZE *retsize, int last_line, WCHAR **p_retstr, int tabwidth, int *pprefix_offset, ellipsis_data *pellip)
 
static void TEXT_DrawUnderscore (HDC hdc, int x, int y, const WCHAR *str, int offset, const RECT *rect)
 
INT WINAPI DrawTextExWorker (HDC hdc, LPWSTR str, INT i_count, LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp)
 

Variables

static const WCHAR ELLIPSISW [] = {'.','.','.', 0}
 
static const WCHAR KinsokuClassA []
 

Macro Definition Documentation

◆ ALPHA_PREFIX

#define ALPHA_PREFIX   30 /* Win16: Alphabet prefix */

Definition at line 114 of file text.c.

◆ assert

#define assert (   e)    ((e) ? (void)0 : _font_assert(#e, __FILE__, __LINE__))

Definition at line 47 of file text.c.

◆ BACK_SLASH

#define BACK_SLASH   '\\'

Definition at line 118 of file text.c.

◆ CR

#define CR   13

Definition at line 111 of file text.c.

◆ FORWARD_SLASH

#define FORWARD_SLASH   '/'

Definition at line 117 of file text.c.

◆ KANA_PREFIX

#define KANA_PREFIX   31 /* Win16: Katakana prefix */

Definition at line 115 of file text.c.

◆ LF

#define LF   10

Definition at line 110 of file text.c.

◆ MAX_BUFFER

#define MAX_BUFFER   1024

Definition at line 1065 of file text.c.

◆ PREFIX

#define PREFIX   38

Definition at line 113 of file text.c.

◆ SPACE

#define SPACE   32

Definition at line 112 of file text.c.

◆ TAB

#define TAB   9

Definition at line 109 of file text.c.

Typedef Documentation

◆ ellipsis_data

Function Documentation

◆ _font_assert()

void _font_assert ( const char msg,
const char file,
int  line 
)

Definition at line 54 of file text.c.

55{
56 /* Assertion failed at foo.c line 45: x<y */
57 DbgPrint("Assertion failed at %s line %d: %s\n", file, line, msg);
58#ifdef _WIN32K_
60#else
61 ExitProcess(3);
62 for(;;); /* eliminate warning by mingw */
63#endif
64}
#define msg(x)
Definition: auth_time.c:54
#define FALSE
Definition: types.h:117
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
#define DbgPrint
Definition: hal.h:12
#define ASSERT(a)
Definition: mode.c:44
Definition: fci.c:127
Definition: parser.c:49

◆ DrawTextExWorker()

INT WINAPI DrawTextExWorker ( HDC  hdc,
LPWSTR  str,
INT  i_count,
LPRECT  rect,
UINT  flags,
LPDRAWTEXTPARAMS  dtp 
)

Definition at line 1071 of file text.c.

1077{
1078 SIZE size;
1079 const WCHAR *strPtr;
1080 WCHAR *retstr, *p_retstr;
1081 size_t size_retstr;
1083 int len, lh, count=i_count;
1085 int lmargin = 0, rmargin = 0;
1086 int x = rect->left, y = rect->top;
1087 int width = rect->right - rect->left;
1088 int max_width = 0;
1089 int last_line;
1090 int tabwidth /* to keep gcc happy */ = 0;
1091 int prefix_offset;
1092 ellipsis_data ellip;
1093 BOOL invert_y=FALSE;
1094
1095 HRGN hrgn = 0;
1096
1097#ifdef _WIN32K_
1098 TRACE("%S, %d, %08x\n", str, count, flags);
1099#else
1100 TRACE("%s, %d, [%s] %08x\n", debugstr_wn (str, count), count,
1102#endif
1103 if (dtp) TRACE("Params: iTabLength=%d, iLeftMargin=%d, iRightMargin=%d\n",
1104 dtp->iTabLength, dtp->iLeftMargin, dtp->iRightMargin);
1105
1106 if (!str) return 0;
1107
1108 strPtr = str;
1109
1110 if (flags & DT_SINGLELINE)
1111 flags &= ~DT_WORDBREAK;
1112#ifdef _WIN32K_
1114#else
1116#endif
1118 lh = tm.tmHeight + tm.tmExternalLeading;
1119 else
1120 lh = tm.tmHeight;
1121
1122 if (str[0] && count == 0)
1123 return lh;
1124
1125 if (dtp && dtp->cbSize != sizeof(DRAWTEXTPARAMS))
1126 return 0;
1127#ifdef _WIN32K_
1129 {
1130 SIZE window_ext, viewport_ext;
1131 GreGetWindowExtEx(hdc, &window_ext);
1132 GreGetViewportExtEx(hdc, &viewport_ext);
1133 if ((window_ext.cy > 0) != (viewport_ext.cy > 0))
1134 invert_y = TRUE;
1135 }
1136#else
1138 {
1139 SIZE window_ext, viewport_ext;
1140 GetWindowExtEx(hdc, &window_ext);
1141 GetViewportExtEx(hdc, &viewport_ext);
1142 if ((window_ext.cy > 0) != (viewport_ext.cy > 0))
1143 invert_y = TRUE;
1144 }
1145#endif
1146 if (count == -1)
1147 {
1148#ifdef _WIN32K_
1149 count = wcslen(str);
1150#else
1151 count = strlenW(str);
1152#endif
1153 if (count == 0)
1154 {
1155 if( flags & DT_CALCRECT)
1156 {
1157 rect->right = rect->left;
1158 if( flags & DT_SINGLELINE)
1159 rect->bottom = rect->top + (invert_y ? -lh : lh);
1160 else
1161 rect->bottom = rect->top;
1162 }
1163 return lh;
1164 }
1165 }
1166
1167 if (dtp)
1168 {
1169 lmargin = dtp->iLeftMargin;
1170 rmargin = dtp->iRightMargin;
1171 if (!(flags & (DT_CENTER | DT_RIGHT)))
1172 x += lmargin;
1173 dtp->uiLengthDrawn = 0; /* This param RECEIVES number of chars processed */
1174 }
1175
1176 if (flags & DT_EXPANDTABS)
1177 {
1178 int tabstop = ((flags & DT_TABSTOP) && dtp && dtp->iTabLength) ? dtp->iTabLength : 8;
1179 tabwidth = tm.tmAveCharWidth * tabstop;
1180 }
1181
1182 if (flags & DT_CALCRECT) flags |= DT_NOCLIP;
1183#ifndef _WIN32K_
1184 if (!(flags & DT_NOCLIP) )
1185 {
1186 int hasClip;
1187 hrgn = CreateRectRgn(0,0,0,0);
1188 if (hrgn)
1189 {
1190 hasClip = GetClipRgn(hdc, hrgn);
1191 // If the region to be retrieved is NULL, the return value is 0.
1192 if (hasClip != 1)
1193 {
1195 hrgn = NULL;
1196 }
1197 IntersectClipRect(hdc, rect->left, rect->top, rect->right, rect->bottom);
1198 }
1199 }
1200#else
1201 if (!(flags & DT_NOCLIP) )
1202 {
1203 int hasClip;
1204 hrgn = NtGdiCreateRectRgn(0,0,0,0);
1205 if (hrgn)
1206 {
1207 hasClip = NtGdiGetRandomRgn(hdc, hrgn, CLIPRGN);
1208 if (hasClip != 1)
1209 {
1211 hrgn = NULL;
1212 }
1213 NtGdiIntersectClipRect(hdc, rect->left, rect->top, rect->right, rect->bottom);
1214 }
1215 }
1216#endif
1217 if (flags & DT_MODIFYSTRING)
1218 {
1219 size_retstr = (count + 4) * sizeof (WCHAR);
1220#ifdef _WIN32K_
1221 retstr = ExAllocatePoolWithTag(PagedPool, size_retstr, USERTAG_RTL);
1222#else
1223 retstr = HeapAlloc(GetProcessHeap(), 0, size_retstr);
1224#endif
1225 if (!retstr) return 0;
1226 memcpy (retstr, str, size_retstr);
1227 }
1228 else
1229 {
1230 size_retstr = 0;
1231 retstr = NULL;
1232 }
1233 p_retstr = retstr;
1234
1235 do
1236 {
1237 len = sizeof(line)/sizeof(line[0]);
1238 if (invert_y)
1239 last_line = !(flags & DT_NOCLIP) && y - ((flags & DT_EDITCONTROL) ? 2*lh-1 : lh) < rect->bottom;
1240 else
1241 last_line = !(flags & DT_NOCLIP) && y + ((flags & DT_EDITCONTROL) ? 2*lh-1 : lh) > rect->bottom;
1242 strPtr = TEXT_NextLineW(hdc, strPtr, &count, line, &len, width, flags, &size, last_line, &p_retstr, tabwidth, &prefix_offset, &ellip);
1243
1244#ifdef __REACTOS__
1245 if (flags & DT_CENTER)
1246 {
1247 if (((rect->right - rect->left) < size.cx) && (flags & DT_CALCRECT))
1248 {
1249 x = rect->left + size.cx;
1250 }
1251 else
1252 {
1253 x = (rect->left + rect->right - size.cx) / 2;
1254 }
1255 }
1256#else
1257 if (flags & DT_CENTER) x = (rect->left + rect->right -
1258 size.cx) / 2;
1259#endif
1260 else if (flags & DT_RIGHT) x = rect->right - size.cx;
1261
1262 if (flags & DT_SINGLELINE)
1263 {
1264#ifdef __REACTOS__
1265 if (flags & DT_VCENTER) y = rect->top +
1266 (rect->bottom - rect->top + (invert_y ? size.cy : -size.cy)) / 2;
1267 else if (flags & DT_BOTTOM)
1268 y = rect->bottom + (invert_y ? size.cy : -size.cy);
1269#else
1270 if (flags & DT_VCENTER) y = rect->top +
1271 (rect->bottom - rect->top) / 2 - size.cy / 2;
1272 else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
1273#endif
1274 }
1275
1276 if (!(flags & DT_CALCRECT))
1277 {
1278 const WCHAR *str = line;
1279 int xseg = x;
1280 while (len)
1281 {
1282 int len_seg;
1283 SIZE size;
1284 if ((flags & DT_EXPANDTABS))
1285 {
1286 const WCHAR *p;
1287 p = str; while (p < str+len && *p != TAB) p++;
1288 len_seg = p - str;
1289 if (len_seg != len &&
1290#ifdef _WIN32K_
1291 !GreGetTextExtentW(hdc, str, len_seg, &size, 0))
1292#else
1293 !GetTextExtentPointW(hdc, str, len_seg, &size))
1294#endif
1295 {
1296#ifdef _WIN32K_
1298#else
1299 HeapFree (GetProcessHeap(), 0, retstr);
1300#endif
1301 return 0;
1302 }
1303 }
1304 else
1305 len_seg = len;
1306#ifdef _WIN32K_
1307 if (!UserExtTextOutW( hdc, xseg, y,
1308 ((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
1309 ((flags & DT_RTLREADING) ? ETO_RTLREADING : 0),
1310 rect, str, len_seg))
1311#else
1312 if (!ExtTextOutW( hdc, xseg, y,
1313 ((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
1314 ((flags & DT_RTLREADING) ? ETO_RTLREADING : 0),
1315 rect, str, len_seg, NULL ))
1316#endif
1317 {
1318#ifdef _WIN32K_
1320#else
1321 HeapFree (GetProcessHeap(), 0, retstr);
1322#endif
1323 return 0;
1324 }
1325 if (prefix_offset != -1 && prefix_offset < len_seg)
1326 {
1327 TEXT_DrawUnderscore (hdc, xseg, y + tm.tmAscent + 1, str, prefix_offset, (flags & DT_NOCLIP) ? NULL : rect);
1328 }
1329 len -= len_seg;
1330 str += len_seg;
1331 if (len)
1332 {
1333 assert ((flags & DT_EXPANDTABS) && *str == TAB);
1334 len--; str++;
1335 xseg += ((size.cx/tabwidth)+1)*tabwidth;
1336 if (prefix_offset != -1)
1337 {
1338 if (prefix_offset < len_seg)
1339 {
1340 /* We have just drawn an underscore; we ought to
1341 * figure out where the next one is. I am going
1342 * to leave it for now until I have a better model
1343 * for the line, which will make reprefixing easier.
1344 * This is where ellip would be used.
1345 */
1346 prefix_offset = -1;
1347 }
1348 else
1349 prefix_offset -= len_seg;
1350 }
1351 }
1352 }
1353 }
1354 else if (size.cx > max_width)
1355 max_width = size.cx;
1356
1357 y += invert_y ? -lh : lh;
1358 if (dtp)
1359 dtp->uiLengthDrawn += len;
1360 }
1361 while (strPtr && !last_line);
1362
1363#ifndef _WIN32K_
1364 if (!(flags & DT_NOCLIP) )
1365 {
1366 SelectClipRgn(hdc, hrgn); // This should be NtGdiExtSelectClipRgn, but due to ReactOS build rules this option is next:
1367 GdiFlush(); // Flush the batch and level up! See CORE-16498.
1368 if (hrgn)
1369 {
1371 }
1372 }
1373#else
1374 if (!(flags & DT_NOCLIP) )
1375 {
1377 if (hrgn)
1378 {
1380 }
1381 }
1382#endif
1383
1384 if (flags & DT_CALCRECT)
1385 {
1386 rect->right = rect->left + max_width;
1387 rect->bottom = y;
1388 if (dtp)
1389 rect->right += lmargin + rmargin;
1390 }
1391 if (retstr)
1392 {
1393 memcpy (str, retstr, size_retstr);
1394#ifdef _WIN32K_
1396#else
1397 HeapFree (GetProcessHeap(), 0, retstr);
1398#endif
1399 }
1400 return y - rect->top;
1401}
static HRGN hrgn
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
int FASTCALL GreGetGraphicsMode(HDC)
Definition: dcutil.c:306
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
unsigned int BOOL
Definition: ntddk_ex.h:94
pKey DeleteObject()
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define debugstr_wn
Definition: kernel32.h:33
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define CLIPRGN
Definition: precomp.h:18
HDC hdc
Definition: main.c:9
BOOL WINAPI GreGetViewportExtEx(_In_ HDC hdc, _Out_ LPSIZE lpSize)
Definition: coord.c:1416
BOOL WINAPI GreGetWindowExtEx(_In_ HDC hdc, _Out_ LPSIZE lpSize)
Definition: coord.c:1407
__kernel_entry W32KAPI HRGN APIENTRY NtGdiCreateRectRgn(_In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom)
__kernel_entry W32KAPI INT APIENTRY NtGdiExtSelectClipRgn(_In_ HDC hdc, _In_opt_ HRGN hrgn, _In_ INT iMode)
__kernel_entry W32KAPI INT APIENTRY NtGdiIntersectClipRect(_In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom)
Definition: cliprgn.c:486
__kernel_entry W32KAPI INT APIENTRY NtGdiGetRandomRgn(_In_ HDC hdc, _In_ HRGN hrgn, _In_ INT iRgn)
#define strlenW(s)
Definition: unicode.h:28
const WCHAR * str
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
int iRightMargin
Definition: winuser.h:3100
UINT uiLengthDrawn
Definition: winuser.h:3101
LONG cy
Definition: kdterminal.h:28
Definition: time.h:68
BOOL UserExtTextOutW(HDC hdc, INT x, INT y, UINT flags, PRECTL lprc, LPCWSTR lpString, UINT count)
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
BOOL FASTCALL GreGetTextExtentW(HDC hDC, LPCWSTR lpwsz, INT cwc, LPSIZE psize, UINT flOpts)
Definition: text.c:78
BOOL WINAPI GreGetTextMetricsW(_In_ HDC hdc, _Out_ LPTEXTMETRICW lptm)
Definition: text.c:193
#define USERTAG_RTL
Definition: tags.h:270
#define MAX_BUFFER
Definition: text.c:1065
static void TEXT_DrawUnderscore(HDC hdc, int x, int y, const WCHAR *str, int offset, const RECT *rect)
Definition: text.c:894
static const WCHAR * TEXT_NextLineW(HDC hdc, const WCHAR *str, int *count, WCHAR *dest, int *len, int width, DWORD format, SIZE *retsize, int last_line, WCHAR **p_retstr, int tabwidth, int *pprefix_offset, ellipsis_data *pellip)
Definition: text.c:666
#define TAB
Definition: text.c:109
#define assert(e)
Definition: text.c:47
#define GM_COMPATIBLE
Definition: wingdi.h:864
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
int WINAPI GetGraphicsMode(_In_ HDC)
int WINAPI IntersectClipRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
BOOL WINAPI GetTextExtentPointW(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE lpsz)
BOOL WINAPI GdiFlush(void)
Definition: misc.c:44
int WINAPI GetClipRgn(_In_ HDC, _In_ HRGN)
#define RGN_COPY
Definition: wingdi.h:357
#define ETO_CLIPPED
Definition: wingdi.h:648
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCWSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
BOOL WINAPI GetWindowExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:411
BOOL WINAPI GetViewportExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:351
int WINAPI SelectClipRgn(_In_ HDC, _In_opt_ HRGN)
#define DT_EXTERNALLEADING
Definition: winuser.h:533
#define DT_CENTER
Definition: winuser.h:527
#define DT_SINGLELINE
Definition: winuser.h:540
#define DT_TABSTOP
Definition: winuser.h:541
#define DT_NOCLIP
Definition: winuser.h:536
#define DT_RTLREADING
Definition: winuser.h:539
#define DT_MODIFYSTRING
Definition: winuser.h:535
#define DT_VCENTER
Definition: winuser.h:543
#define DT_BOTTOM
Definition: winuser.h:525
#define DT_RIGHT
Definition: winuser.h:538
#define DT_EXPANDTABS
Definition: winuser.h:532
#define DT_CALCRECT
Definition: winuser.h:526
#define DT_EDITCONTROL
Definition: winuser.h:528
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by DrawTextExW(), and DrawTextW().

◆ IsCJKT()

FORCEINLINE BOOL IsCJKT ( WCHAR  wch)

Definition at line 335 of file text.c.

336{
337 if (0x0E00 <= wch && wch <= 0x0E7F)
338 return TRUE; /* Thai */
339
340 if (0x3000 <= wch && wch <= 0x9FFF)
341 return TRUE; /* CJK */
342
343 if (0xAC00 <= wch && wch <= 0xD7FF)
344 return TRUE; /* Korean */
345
346 if (0xFF00 <= wch && wch <= 0xFFEF)
347 return TRUE; /* CJK */
348
349 return FALSE;
350}

Referenced by TEXT_WordBreak().

◆ remainder_is_none_or_newline()

static int remainder_is_none_or_newline ( int  num_chars,
const WCHAR str 
)
static

Definition at line 626 of file text.c.

627{
628 if (!num_chars) return TRUE;
629 if (*str != LF && *str != CR) return FALSE;
630 if (!--num_chars) return TRUE;
631 if (*str == *(str+1)) return FALSE;
632 str++;
633 if (*str != CR && *str != LF) return FALSE;
634 if (--num_chars) return FALSE;
635 return TRUE;
636}
#define LF
Definition: text.c:110
#define CR
Definition: text.c:111

Referenced by TEXT_NextLineW().

◆ TEXT_DrawUnderscore()

static void TEXT_DrawUnderscore ( HDC  hdc,
int  x,
int  y,
const WCHAR str,
int  offset,
const RECT rect 
)
static

Definition at line 894 of file text.c.

895{
896 int prefix_x;
897 int prefix_end;
898 SIZE size;
899 HPEN hpen;
900 HPEN oldPen;
901#ifdef _WIN32K_
903#else
905#endif
906 prefix_x = x + size.cx;
907#ifdef _WIN32K_
909#else
911#endif
912 prefix_end = x + size.cx - 1;
913 /* The above method may eventually be slightly wrong due to kerning etc. */
914
915 /* Check for clipping */
916 if (rect)
917 {
918 if (prefix_x > rect->right || prefix_end < rect->left ||
919 y < rect->top || y > rect->bottom)
920 return; /* Completely outside */
921 /* Partially outside */
922 if (prefix_x < rect->left ) prefix_x = rect->left;
923 if (prefix_end > rect->right) prefix_end = rect->right;
924 }
925#ifdef _WIN32K_
927 oldPen = NtGdiSelectPen (hdc, hpen);
928 GreMoveTo (hdc, prefix_x, y, NULL);
929 NtGdiLineTo (hdc, prefix_end, y);
930 NtGdiSelectPen (hdc, oldPen);
932#else
934 oldPen = SelectObject (hdc, hpen);
935 MoveToEx (hdc, prefix_x, y, NULL);
936 LineTo (hdc, prefix_end, y);
937 SelectObject (hdc, oldPen);
939#endif
940}
static HPEN hpen
COLORREF FASTCALL GreGetTextColor(HDC)
Definition: dcutil.c:80
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
GLintptr offset
Definition: glext.h:5920
BOOL FASTCALL GreMoveTo(HDC hdc, INT x, INT y, LPPOINT pptOut)
Definition: line.c:108
__kernel_entry W32KAPI HPEN APIENTRY NtGdiCreatePen(_In_ INT iPenStyle, _In_ INT iPenWidth, _In_ COLORREF cr, _In_opt_ HBRUSH hbr)
__kernel_entry W32KAPI HPEN APIENTRY NtGdiSelectPen(_In_ HDC hdc, _In_ HPEN hpen)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiLineTo(_In_ HDC hdc, _In_ INT x, _In_ INT y)
COLORREF WINAPI GetTextColor(_In_ HDC)
Definition: text.c:861
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
HPEN WINAPI CreatePen(_In_ int, _In_ int, _In_ COLORREF)
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
#define PS_SOLID
Definition: wingdi.h:586

Referenced by DrawTextExWorker().

◆ TEXT_Ellipsify()

static void TEXT_Ellipsify ( HDC  hdc,
WCHAR str,
unsigned int  max_len,
unsigned int len_str,
int  width,
SIZE size,
WCHAR modstr,
int len_before,
int len_ellip 
)
static

Definition at line 159 of file text.c.

163{
164 unsigned int len_ellipsis;
165 unsigned int lo, mid, hi;
166 len_ellipsis = strlenW (ELLIPSISW);
167 if (len_ellipsis > max_len) len_ellipsis = max_len;
168 if (*len_str > max_len - len_ellipsis)
169 *len_str = max_len - len_ellipsis;
170
171 /* First do a quick binary search to get an upper bound for *len_str. */
172 if (*len_str > 0 &&
173#ifdef _WIN32K_
174 GreGetTextExtentExW(hdc, str, *len_str, width, NULL, NULL, size, 0) &&
175#else
176 GetTextExtentExPointW(hdc, str, *len_str, width, NULL, NULL, size) &&
177#endif
178 size->cx > width)
179 {
180 for (lo = 0, hi = *len_str; lo < hi; )
181 {
182 mid = (lo + hi) / 2;
183#ifdef _WIN32K_
184 if (!GreGetTextExtentExW(hdc, str, mid, width, NULL, NULL, size, 0))
185#else
187#endif
188 break;
189 if (size->cx > width)
190 hi = mid;
191 else
192 lo = mid + 1;
193 }
194 *len_str = hi;
195 }
196 /* Now this should take only a couple iterations at most. */
197 for ( ; ; )
198 {
199 memcpy(str + *len_str, ELLIPSISW, len_ellipsis*sizeof(WCHAR));
200#ifdef _WIN32K_
201 if (!GreGetTextExtentExW (hdc, str, *len_str + len_ellipsis, width,
202 NULL, NULL, size, 0)) break;
203#else
204 if (!GetTextExtentExPointW (hdc, str, *len_str + len_ellipsis, width,
205 NULL, NULL, size)) break;
206#endif
207 if (!*len_str || size->cx <= width) break;
208
209 (*len_str)--;
210 }
211 *len_ellip = len_ellipsis;
212 *len_before = *len_str;
213 *len_str += len_ellipsis;
214
215 if (modstr)
216 {
217 memcpy (modstr, str, *len_str * sizeof(WCHAR));
218 modstr[*len_str] = '\0';
219 }
220}
BOOL FASTCALL GreGetTextExtentExW(HDC hDC, LPCWSTR String, ULONG Count, ULONG MaxExtent, PULONG Fit, PULONG Dx, LPSIZE pSize, FLONG fl)
Definition: text.c:135
static const WCHAR ELLIPSISW[]
Definition: text.c:120
BOOL WINAPI GetTextExtentExPointW(_In_ HDC hdc, _In_reads_(cchString) LPCWSTR lpszString, _In_ int cchString, _In_ int nMaxExtent, _Out_opt_ LPINT lpnFit, _Out_writes_to_opt_(cchString, *lpnFit) LPINT lpnDx, _Out_ LPSIZE lpSize)

Referenced by TEXT_NextLineW().

◆ TEXT_NextLineW()

static const WCHAR * TEXT_NextLineW ( HDC  hdc,
const WCHAR str,
int count,
WCHAR dest,
int len,
int  width,
DWORD  format,
SIZE retsize,
int  last_line,
WCHAR **  p_retstr,
int  tabwidth,
int pprefix_offset,
ellipsis_data pellip 
)
static

Definition at line 666 of file text.c.

671{
672 int i = 0, j = 0;
673 int plen = 0;
674 SIZE size = {0, 0};
675 int maxl = *len;
676 int seg_i, seg_count, seg_j;
677 int max_seg_width;
678 int num_fit;
679 int word_broken;
680 int line_fits;
681 unsigned int j_in_seg;
682 int ellipsified;
683 *pprefix_offset = -1;
684
685 /* For each text segment in the line */
686
687 retsize->cy = 0;
688 while (*count)
689 {
690
691 /* Skip any leading tabs */
692
693 if (str[i] == TAB && (format & DT_EXPANDTABS))
694 {
695 plen = ((plen/tabwidth)+1)*tabwidth;
696 (*count)--; if (j < maxl) dest[j++] = str[i++]; else i++;
697 while (*count && str[i] == TAB)
698 {
699 plen += tabwidth;
700 (*count)--; if (j < maxl) dest[j++] = str[i++]; else i++;
701 }
702 }
703
704
705 /* Now copy as far as the next tab or cr/lf or eos */
706
707 seg_i = i;
708 seg_count = *count;
709 seg_j = j;
710
711 while (*count &&
712 (str[i] != TAB || !(format & DT_EXPANDTABS)) &&
713 ((str[i] != CR && str[i] != LF) || (format & DT_SINGLELINE)))
714 {
715 if ((format & DT_NOPREFIX) || *count <= 1)
716 {
717 (*count)--; if (j < maxl) dest[j++] = str[i++]; else i++;
718 continue;
719 }
720
721 if (str[i] == PREFIX || str[i] == ALPHA_PREFIX) {
722 (*count)--, i++; /* Throw away the prefix itself */
723 if (str[i] == PREFIX)
724 {
725 /* Swallow it before we see it again */
726 (*count)--; if (j < maxl) dest[j++] = str[i++]; else i++;
727 }
728 else if (*pprefix_offset == -1 || *pprefix_offset >= seg_j)
729 {
730 *pprefix_offset = j;
731 }
732 /* else the previous prefix was in an earlier segment of the
733 * line; we will leave it to the drawing code to catch this
734 * one.
735 */
736 }
737 else if (str[i] == KANA_PREFIX)
738 {
739 /* Throw away katakana access keys */
740 (*count)--, i++; /* skip the prefix */
741 (*count)--, i++; /* skip the letter */
742 }
743 else
744 {
745 (*count)--; if (j < maxl) dest[j++] = str[i++]; else i++;
746 }
747 }
748
749
750 /* Measure the whole text segment and possibly WordBreak and
751 * ellipsify it
752 */
753
754 j_in_seg = j - seg_j;
755 max_seg_width = width - plen;
756#ifdef _WIN32K_
757 GreGetTextExtentExW (hdc, dest + seg_j, j_in_seg, max_seg_width, (PULONG)&num_fit, NULL, &size, 0);
758#else
759 GetTextExtentExPointW (hdc, dest + seg_j, j_in_seg, max_seg_width, &num_fit, NULL, &size);
760#endif
761
762 /* The Microsoft handling of various combinations of formats is weird.
763 * The following may very easily be incorrect if several formats are
764 * combined, and may differ between versions (to say nothing of the
765 * several bugs in the Microsoft versions).
766 */
767 word_broken = 0;
768 line_fits = (num_fit >= j_in_seg);
769 if (!line_fits && (format & DT_WORDBREAK))
770 {
771 const WCHAR *s;
772 unsigned int chars_used;
773 TEXT_WordBreak (hdc, dest+seg_j, maxl-seg_j, &j_in_seg,
774 max_seg_width, format, num_fit, &chars_used, &size);
775 line_fits = (size.cx <= max_seg_width);
776 /* and correct the counts */
777 TEXT_SkipChars (count, &s, seg_count, str+seg_i, i-seg_i,
778 chars_used, !(format & DT_NOPREFIX));
779 i = s - str;
780 word_broken = 1;
781 }
782 pellip->before = j_in_seg;
783 pellip->under = 0;
784 pellip->after = 0;
785 pellip->len = 0;
786 ellipsified = 0;
787 if (!line_fits && (format & DT_PATH_ELLIPSIS))
788 {
789 TEXT_PathEllipsify (hdc, dest + seg_j, maxl-seg_j, &j_in_seg,
790 max_seg_width, &size, *p_retstr, pellip);
791 line_fits = (size.cx <= max_seg_width);
792 ellipsified = 1;
793 }
794 /* NB we may end up ellipsifying a word-broken or path_ellipsified
795 * string */
796 if ((!line_fits && (format & DT_WORD_ELLIPSIS)) ||
797 ((format & DT_END_ELLIPSIS) &&
798 ((last_line && *count) ||
799 (remainder_is_none_or_newline (*count, &str[i]) && !line_fits))))
800 {
801 int before, len_ellipsis;
802 TEXT_Ellipsify (hdc, dest + seg_j, maxl-seg_j, &j_in_seg,
803 max_seg_width, &size, *p_retstr, &before, &len_ellipsis);
804 if (before > pellip->before)
805 {
806 /* We must have done a path ellipsis too */
807 pellip->after = before - pellip->before - pellip->len;
808 /* Leave the len as the length of the first ellipsis */
809 }
810 else
811 {
812 /* If we are here after a path ellipsification it must be
813 * because even the ellipsis itself didn't fit.
814 */
815 assert (pellip->under == 0 && pellip->after == 0);
816 pellip->before = before;
817 pellip->len = len_ellipsis;
818 /* pellip->after remains as zero as does
819 * pellip->under
820 */
821 }
822 line_fits = (size.cx <= max_seg_width);
823 ellipsified = 1;
824 }
825 /* As an optimisation if we have ellipsified and we are expanding
826 * tabs and we haven't reached the end of the line we can skip to it
827 * now rather than going around the loop again.
828 */
829 if ((format & DT_EXPANDTABS) && ellipsified)
830 {
831 if (format & DT_SINGLELINE)
832 *count = 0;
833 else
834 {
835 while ((*count) && str[i] != CR && str[i] != LF)
836 {
837 (*count)--, i++;
838 }
839 }
840 }
841
842 j = seg_j + j_in_seg;
843 if (*pprefix_offset >= seg_j + pellip->before)
844 {
845 *pprefix_offset = TEXT_Reprefix (str + seg_i, i - seg_i, pellip);
846 if (*pprefix_offset != -1)
847 *pprefix_offset += seg_j;
848 }
849
850 plen += size.cx;
851 if (size.cy > retsize->cy)
852 retsize->cy = size.cy;
853
854 if (word_broken)
855 break;
856 else if (!*count)
857 break;
858 else if (str[i] == CR || str[i] == LF)
859 {
860 (*count)--, i++;
861 if (*count && (str[i] == CR || str[i] == LF) && str[i] != str[i-1])
862 {
863 (*count)--, i++;
864 }
865 break;
866 }
867 /* else it was a Tab and we go around again */
868 }
869
870 retsize->cx = plen;
871 *len = j;
872 if (*count)
873 return (&str[i]);
874 else
875 return NULL;
876}
GLdouble s
Definition: gl.h:2039
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static char * dest
Definition: rtl.c:135
LONG cx
Definition: kdterminal.h:27
__inline int before(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2390
uint32_t * PULONG
Definition: typedefs.h:59
static int remainder_is_none_or_newline(int num_chars, const WCHAR *str)
Definition: text.c:626
#define KANA_PREFIX
Definition: text.c:115
static void TEXT_Ellipsify(HDC hdc, WCHAR *str, unsigned int max_len, unsigned int *len_str, int width, SIZE *size, WCHAR *modstr, int *len_before, int *len_ellip)
Definition: text.c:159
#define ALPHA_PREFIX
Definition: text.c:114
static int TEXT_Reprefix(const WCHAR *str, unsigned int ns, const ellipsis_data *pe)
Definition: text.c:588
static void TEXT_PathEllipsify(HDC hdc, WCHAR *str, unsigned int max_len, unsigned int *len_str, int width, SIZE *size, WCHAR *modstr, ellipsis_data *pellip)
Definition: text.c:265
static void TEXT_WordBreak(HDC hdc, WCHAR *str, unsigned int max_str, unsigned int *len_str, int width, int format, unsigned int chars_fit, unsigned int *chars_used, SIZE *size)
Definition: text.c:426
#define PREFIX
Definition: text.c:113
static void TEXT_SkipChars(int *new_count, const WCHAR **new_str, int start_count, const WCHAR *start_str, int max, int n, int prefix)
Definition: text.c:540
#define DT_NOPREFIX
Definition: winuser.h:537
#define DT_END_ELLIPSIS
Definition: winuser.h:529
#define DT_WORDBREAK
Definition: winuser.h:544
#define DT_WORD_ELLIPSIS
Definition: winuser.h:531
#define DT_PATH_ELLIPSIS
Definition: winuser.h:530

Referenced by DrawTextExWorker().

◆ TEXT_PathEllipsify()

static void TEXT_PathEllipsify ( HDC  hdc,
WCHAR str,
unsigned int  max_len,
unsigned int len_str,
int  width,
SIZE size,
WCHAR modstr,
ellipsis_data pellip 
)
static

Definition at line 265 of file text.c.

268{
269 int len_ellipsis;
270 int len_trailing;
271 int len_under;
272 WCHAR *lastBkSlash, *lastFwdSlash, *lastSlash;
273 len_ellipsis = strlenW (ELLIPSISW);
274 if (!max_len) return;
275 if (len_ellipsis >= max_len) len_ellipsis = max_len - 1;
276 if (*len_str + len_ellipsis >= max_len)
277 *len_str = max_len - len_ellipsis-1;
278 /* Hopefully this will never happen, otherwise it would probably lose
279 * the wrong character
280 */
281 str[*len_str] = '\0'; /* to simplify things */
282#ifdef _WIN32K_
283 lastBkSlash = wcsrchr (str, BACK_SLASH);
284 lastFwdSlash = wcsrchr (str, FORWARD_SLASH);
285#else
286 lastBkSlash = strrchrW (str, BACK_SLASH);
287 lastFwdSlash = strrchrW (str, FORWARD_SLASH);
288#endif
289 lastSlash = lastBkSlash > lastFwdSlash ? lastBkSlash : lastFwdSlash;
290 if (!lastSlash) lastSlash = str;
291 len_trailing = *len_str - (lastSlash - str);
292
293 /* overlap-safe movement to the right */
294 memmove (lastSlash+len_ellipsis, lastSlash, len_trailing * sizeof(WCHAR));
295 memcpy (lastSlash, ELLIPSISW, len_ellipsis*sizeof(WCHAR));
296 len_trailing += len_ellipsis;
297 /* From this point on lastSlash actually points to the ellipsis in front
298 * of the last slash and len_trailing includes the ellipsis
299 */
300
301 len_under = 0;
302 for ( ; ; )
303 {
304#ifdef _WIN32K_
305 if (!GreGetTextExtentExW (hdc, str, *len_str + len_ellipsis, width,
306 NULL, NULL, size, 0)) break;
307#else
308 if (!GetTextExtentExPointW (hdc, str, *len_str + len_ellipsis, width,
309 NULL, NULL, size)) break;
310#endif
311 if (lastSlash == str || size->cx <= width) break;
312
313 /* overlap-safe movement to the left */
314 memmove (lastSlash-1, lastSlash, len_trailing * sizeof(WCHAR));
315 lastSlash--;
316 len_under++;
317
318 assert (*len_str);
319 (*len_str)--;
320 }
321 pellip->before = lastSlash-str;
322 pellip->len = len_ellipsis;
323 pellip->under = len_under;
324 pellip->after = len_trailing - len_ellipsis;
325 *len_str += len_ellipsis;
326
327 if (modstr)
328 {
329 memcpy(modstr, str, *len_str * sizeof(WCHAR));
330 modstr[*len_str] = '\0';
331 }
332}
#define wcsrchr
Definition: compat.h:16
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define strrchrW(s, c)
Definition: unicode.h:35
#define BACK_SLASH
Definition: text.c:118
#define FORWARD_SLASH
Definition: text.c:117

Referenced by TEXT_NextLineW().

◆ TEXT_Reprefix()

static int TEXT_Reprefix ( const WCHAR str,
unsigned int  ns,
const ellipsis_data pe 
)
static

Definition at line 588 of file text.c.

590{
591 int result = -1;
592 unsigned int i;
593 unsigned int n = pe->before + pe->under + pe->after;
594 assert (n <= ns);
595 for (i = 0; i < n; i++, str++)
596 {
597 if (i == (unsigned int) pe->before)
598 {
599 /* Reached the path ellipsis; jump over it */
600 if (ns < (unsigned int) pe->under) break;
601 str += pe->under;
602 ns -= pe->under;
603 i += pe->under;
604 if (!pe->after) break; /* Nothing after the path ellipsis */
605 }
606 if (!ns) break;
607 ns--;
608 if (*str++ == PREFIX || *str == ALPHA_PREFIX)
609 {
610 str++;
611 if (!ns) break;
612 if (*str != PREFIX)
613 result = (i < (unsigned int) pe->before || pe->under == 0) ? i : i - pe->under + pe->len;
614 /* pe->len may be non-zero while pe_under is zero */
615 ns--;
616 }
617 }
618 return result;
619}
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
GLdouble n
Definition: glext.h:7729
GLuint64EXT * result
Definition: glext.h:11304
Definition: mxnamespace.c:45

Referenced by TEXT_NextLineW().

◆ TEXT_SkipChars()

static void TEXT_SkipChars ( int new_count,
const WCHAR **  new_str,
int  start_count,
const WCHAR start_str,
int  max,
int  n,
int  prefix 
)
static

Definition at line 540 of file text.c.

543{
544 /* This is specific to wide characters, MSDN doesn't say anything much
545 * about Unicode surrogates yet and it isn't clear if _wcsinc will
546 * correctly handle them so we'll just do this the easy way for now
547 */
548
549 if (prefix)
550 {
551 const WCHAR *str_on_entry = start_str;
552 assert (max >= n);
553 max -= n;
554 while (n--)
555 {
556 if ((*start_str == PREFIX || *start_str == ALPHA_PREFIX) && max--)
557 start_str++;
558 start_str++;
559 }
560 start_count -= (start_str - str_on_entry);
561 }
562 else
563 {
564 start_str += n;
565 start_count -= n;
566 }
567 *new_str = start_str;
568 *new_count = start_count;
569}
#define max(a, b)
Definition: svc.c:63

Referenced by TEXT_NextLineW().

◆ TEXT_WordBreak()

static void TEXT_WordBreak ( HDC  hdc,
WCHAR str,
unsigned int  max_str,
unsigned int len_str,
int  width,
int  format,
unsigned int  chars_fit,
unsigned int chars_used,
SIZE size 
)
static

Definition at line 426 of file text.c.

430{
431 WCHAR *p;
432 int word_fits;
434 assert (chars_fit < *len_str);
435
436 /* Work back from the last character that did fit to either a space or the
437 * last character of a word, whichever is met first.
438 */
439 p = str + chars_fit; /* The character that doesn't fit */
440 word_fits = TRUE;
441 if (!chars_fit)
442 word_fits = FALSE;
443 else if (*p == SPACE) /* chars_fit < *len_str so this is valid */
444 p--; /* the word just fitted */
445 else
446 {
447 while (p > str && *(--p) != SPACE && (!IsCJKT(p[1]) ||
448 p[1] == L'\0' || wcschr(KinsokuClassA, p[1]) != NULL))
449 ;
450 word_fits = (p != str || *p == SPACE || IsCJKT(p[1]));
451 }
452 /* If there was one. */
453 if (word_fits)
454 {
455 int next_is_space;
456 /* break the line before/after that character */
457 if (!(format & (DT_RIGHT | DT_CENTER)) || *p != SPACE)
458 p++;
459 next_is_space = (unsigned int) (p - str) < *len_str && *p == SPACE;
460 *len_str = p - str;
461 /* and if the next character is a space then discard it. */
462 *chars_used = *len_str;
463 if (next_is_space)
464 (*chars_used)++;
465 }
466 /* Suppose there was none. */
467 else
468 {
471 {
472 /* break the word after the last character that fits (there must be
473 * at least one). */
474 if (!chars_fit)
475 ++chars_fit;
476 *len_str = chars_fit;
477 *chars_used = chars_fit;
478
479 /* FIXME - possible error. Since the next character is now removed
480 * this could make the text longer so that it no longer fits, and
481 * so we need a loop to test and shrink.
482 */
483 }
484 /* Otherwise */
485 else
486 {
487 /* discard any trailing space. */
488 const WCHAR *e = str + *len_str;
489 p = str + chars_fit;
490 while (p < e && *p != SPACE)
491 p++;
492 *chars_used = p - str;
493 if (p < e) /* i.e. loop failed because *p == SPACE */
494 (*chars_used)++;
495
496 /* include the whole word; it may be ellipsified later */
497 *len_str = p - str;
498 /* Possible optimisation; if DT_WORD_ELLIPSIS only use chars_fit+1
499 * so that it will be too long
500 */
501 }
502 }
503 /* Remeasure the string */
504#ifdef _WIN32K_
505 GreGetTextExtentExW (hdc, str, *len_str, 0, NULL, NULL, size, 0);
506#else
507 GetTextExtentExPointW (hdc, str, *len_str, 0, NULL, NULL, size);
508#endif
509}
#define wcschr
Definition: compat.h:17
#define e
Definition: ke_i.h:82
#define L(x)
Definition: ntvdm.h:50
#define SPACE
Definition: text.c:112
FORCEINLINE BOOL IsCJKT(WCHAR wch)
Definition: text.c:335
static const WCHAR KinsokuClassA[]
Definition: text.c:353

Referenced by TEXT_NextLineW().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( text  )

Variable Documentation

◆ ELLIPSISW

const WCHAR ELLIPSISW[] = {'.','.','.', 0}
static

Definition at line 120 of file text.c.

Referenced by TEXT_Ellipsify(), and TEXT_PathEllipsify().

◆ KinsokuClassA

const WCHAR KinsokuClassA[]
static
Initial value:
=
{
0x2010, 0x2013, 0x2019, 0x201D, 0x203C, 0x2047, 0x2048, 0x2049, 0x3001,
0x3002, 0x3005, 0x3009, 0x300B, 0x300D, 0x300F, 0x3011, 0x3015, 0x3017,
0x3019, 0x301C, 0x301F, 0x303B, 0x3041, 0x3043, 0x3045, 0x3047, 0x3049,
0x3063, 0x3083, 0x3085, 0x3087, 0x308E, 0x3095, 0x3096, 0x30A0, 0x30A1,
0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30C3, 0x30E3, 0x30E5, 0x30E7, 0x30EE,
0x30F5, 0x30F6, 0x30FB, 0x30FC, 0x30FD, 0x30FE, 0x31F0, 0x31F1, 0x31F2,
0x31F3, 0x31F4, 0x31F5, 0x31F6, 0x31F7, 0x31F8, 0x31F9, 0x31FA, 0x31FB,
0x31FC, 0x31FD, 0x31FE, 0x31FF, 0xFF01, 0xFF09, 0xFF0C, 0xFF0E, 0xFF1A,
0xFF1B, 0xFF1F, 0xFF3D, 0xFF5D, 0xFF60, 0
}

Definition at line 353 of file text.c.

Referenced by TEXT_WordBreak().