ReactOS  0.4.13-dev-544-gede3fdd
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)
 
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 1066 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_
59  ASSERT(FALSE);
60 #else
61  ExitProcess(3);
62  for(;;); /* eliminate warning by mingw */
63 #endif
64 }
#define DbgPrint
Definition: loader.c:25
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1517
Definition: parser.c:48
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define msg(x)
Definition: auth_time.c:54
Definition: fci.c:126

◆ DrawTextExWorker()

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

Definition at line 1072 of file text.c.

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

Referenced by DrawTextExW(), and DrawTextW().

◆ IsCJKT()

BOOL IsCJKT ( WCHAR  wch)
inline

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 }
#define TRUE
Definition: types.h:120

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 TRUE
Definition: types.h:120
#define LF
Definition: text.c:110
const WCHAR * str
#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_
908  GreGetTextExtentW (hdc, str, offset+1, &size, 0);
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);
938  DeleteObject (hpen);
939 #endif
940 }
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1155
HPEN WINAPI CreatePen(_In_ int, _In_ int, _In_ COLORREF)
BOOL FASTCALL GreGetTextExtentW(HDC hDC, LPCWSTR lpwsz, INT cwc, LPSIZE psize, UINT flOpts)
Definition: text.c:36
GLintptr offset
Definition: glext.h:5920
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static HPEN hpen
& rect
Definition: startmenu.cpp:1413
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
#define PS_SOLID
Definition: wingdi.h:585
__kernel_entry W32KAPI BOOL APIENTRY NtGdiLineTo(_In_ HDC hdc, _In_ INT x, _In_ INT y)
__kernel_entry W32KAPI HPEN APIENTRY NtGdiSelectPen(_In_ HDC hdc, _In_ HPEN hpen)
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
GLsizeiptr size
Definition: glext.h:5919
GLint left
Definition: glext.h:7726
HDC hdc
Definition: main.c:9
BOOL APIENTRY GetTextExtentPointW(_In_ HDC hdc, _In_reads_(cchString) LPCWSTR lpString, _In_ INT cchString, _Out_ LPSIZE lpsz)
Definition: text.c:268
BOOL FASTCALL GreMoveTo(HDC hdc, INT x, INT y, LPPOINT pptOut)
Definition: line.c:108
COLORREF WINAPI GetTextColor(_In_ HDC hdc)
Definition: text.c:829
__kernel_entry W32KAPI HPEN APIENTRY NtGdiCreatePen(_In_ INT iPenStyle, _In_ INT iPenWidth, _In_ COLORREF cr, _In_opt_ HBRUSH hbr)
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
COLORREF FASTCALL GreGetTextColor(HDC)
Definition: dcutil.c:80
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859

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
186  if (!GetTextExtentExPointW(hdc, str, mid, width, NULL, NULL, size))
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 }
GLint GLint GLsizei width
Definition: gl.h:1546
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
HDC hdc
Definition: main.c:9
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
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)
Definition: text.c:283
BOOL FASTCALL GreGetTextExtentExW(HDC hDC, LPCWSTR String, ULONG Count, ULONG MaxExtent, PULONG Fit, PULONG Dx, LPSIZE pSize, FLONG fl)
Definition: text.c:93

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 }
#define DT_EXPANDTABS
Definition: winuser.h:532
GLint GLint GLsizei width
Definition: gl.h:1546
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 LF
Definition: text.c:110
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define DT_WORDBREAK
Definition: winuser.h:544
__inline int before(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2414
#define DT_NOPREFIX
Definition: winuser.h:537
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define DT_PATH_ELLIPSIS
Definition: winuser.h:530
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
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
#define KANA_PREFIX
Definition: text.c:115
#define TAB
Definition: text.c:109
const WCHAR * str
#define DT_END_ELLIPSIS
Definition: winuser.h:529
smooth NULL
Definition: ftsmooth.c:416
LONG cx
Definition: windef.h:319
#define assert(e)
Definition: text.c:47
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
#define DT_WORD_ELLIPSIS
Definition: winuser.h:531
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
HDC hdc
Definition: main.c:9
static int remainder_is_none_or_newline(int num_chars, const WCHAR *str)
Definition: text.c:626
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
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
static int TEXT_Reprefix(const WCHAR *str, unsigned int ns, const ellipsis_data *pe)
Definition: text.c:588
#define CR
Definition: text.c:111
#define DT_SINGLELINE
Definition: winuser.h:540
#define ALPHA_PREFIX
Definition: text.c:114
unsigned int * PULONG
Definition: retypes.h:1
#define PREFIX
Definition: text.c:113
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)
Definition: text.c:283
static char * dest
Definition: rtl.c:135
LONG cy
Definition: windef.h:320
BOOL FASTCALL GreGetTextExtentExW(HDC hDC, LPCWSTR String, ULONG Count, ULONG MaxExtent, PULONG Fit, PULONG Dx, LPSIZE pSize, FLONG fl)
Definition: text.c:93
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

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 }
GLint GLint GLsizei width
Definition: gl.h:1546
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
#define assert(e)
Definition: text.c:47
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
HDC hdc
Definition: main.c:9
#define FORWARD_SLASH
Definition: text.c:117
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define BACK_SLASH
Definition: text.c:118
WINE_UNICODE_INLINE WCHAR * strrchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:254
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)
Definition: text.c:283
BOOL FASTCALL GreGetTextExtentExW(HDC hDC, LPCWSTR String, ULONG Count, ULONG MaxExtent, PULONG Fit, PULONG Dx, LPSIZE pSize, FLONG fl)
Definition: text.c:93

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 }
GLdouble n
Definition: glext.h:7729
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
const WCHAR * str
#define assert(e)
Definition: text.c:47
Definition: mxnamespace.c:44
#define ALPHA_PREFIX
Definition: text.c:114
#define PREFIX
Definition: text.c:113
GLuint64EXT * result
Definition: glext.h:11304
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

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
GLdouble n
Definition: glext.h:7729
#define assert(e)
Definition: text.c:47
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ALPHA_PREFIX
Definition: text.c:114
#define PREFIX
Definition: text.c:113

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 }
BOOL IsCJKT(WCHAR wch)
Definition: text.c:335
#define TRUE
Definition: types.h:120
#define DT_WORDBREAK
Definition: winuser.h:544
#define DT_RIGHT
Definition: winuser.h:538
#define SPACE
Definition: text.c:112
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define DT_PATH_ELLIPSIS
Definition: winuser.h:530
#define e
Definition: ke_i.h:82
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
#define assert(e)
Definition: text.c:47
#define DT_WORD_ELLIPSIS
Definition: winuser.h:531
static const WCHAR KinsokuClassA[]
Definition: text.c:353
GLsizeiptr size
Definition: glext.h:5919
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR L[]
Definition: oid.c:1250
HDC hdc
Definition: main.c:9
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)
Definition: text.c:283
#define DT_CENTER
Definition: winuser.h:527
GLfloat GLfloat p
Definition: glext.h:8902
BOOL FASTCALL GreGetTextExtentExW(HDC hDC, LPCWSTR String, ULONG Count, ULONG MaxExtent, PULONG Fit, PULONG Dx, LPSIZE pSize, FLONG fl)
Definition: text.c:93
#define DT_EDITCONTROL
Definition: winuser.h:528
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

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().