00001
00002
00003
00004
00005
00006
00007
00008 #include <string.h>
00009
00010 #include "windef.h"
00011 #include "wingdi.h"
00012 #include "wine/winuser16.h"
00013 #include "wine/unicode.h"
00014 #include "winbase.h"
00015 #include "winerror.h"
00016 #include "winnls.h"
00017 #include "user.h"
00018 #include "debugtools.h"
00019
00020 #ifdef __WIN32OS2__
00021 #define CACHE_GetPattern55AABrush GetPattern55AABrush
00022
00023 #define MapSL(a) a
00024
00025 #define DBG_LOCALLOG DBG_text
00026 #include "dbglocal.h"
00027
00028 #endif
00029
00030 DEFAULT_DEBUG_CHANNEL(text);
00031
00032 #define TAB 9
00033 #define LF 10
00034 #define CR 13
00035 #define SPACE 32
00036 #define PREFIX 38
00037
00038 #define ELLIPSIS "..."
00039 #define FORWARD_SLASH '/'
00040 #define BACK_SLASH '\\'
00041
00042 static const WCHAR SPACEW[] = {' ', 0};
00043 static const WCHAR oW[] = {'o', 0};
00044 static const WCHAR ELLIPSISW[] = {'.','.','.', 0};
00045 static const WCHAR FORWARD_SLASHW[] = {'/', 0};
00046 static const WCHAR BACK_SLASHW[] = {'\\', 0};
00047
00048 #define SWAP_INT(a,b) { int t = a; a = b; b = t; }
00049
00050 static int tabstop = 8;
00051 static int tabwidth;
00052 static int spacewidth;
00053 static int prefix_offset;
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 static const WCHAR *TEXT_NextLineW( HDC hdc, const WCHAR *str, int *count,
00075 WCHAR *dest, int *len, int width, WORD format)
00076 {
00077 int i = 0, j = 0, k;
00078 int plen = 0;
00079 int numspaces;
00080 SIZE size;
00081 int lasttab = 0;
00082 int wb_i = 0, wb_j = 0, wb_count = 0;
00083 int maxl = *len;
00084
00085 while (*count && j < maxl)
00086 {
00087 switch (str[i])
00088 {
00089 case CR:
00090 case LF:
00091 if (!(format & DT_SINGLELINE))
00092 {
00093 if ((*count > 1) && (str[i] == CR) && (str[i+1] == LF))
00094 {
00095 (*count)--;
00096 i++;
00097 }
00098 i++;
00099 *len = j;
00100 (*count)--;
00101 return (&str[i]);
00102 }
00103 dest[j++] = str[i++];
00104 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
00105 (format & DT_WORDBREAK))
00106 {
00107 if (!GetTextExtentPointW(hdc, &dest[j-1], 1, &size))
00108 return NULL;
00109 plen += size.cx;
00110 }
00111 break;
00112
00113 case PREFIX:
00114 if (!(format & DT_NOPREFIX) && *count > 1)
00115 {
00116 if (str[++i] == PREFIX)
00117 (*count)--;
00118 else {
00119 prefix_offset = j;
00120 break;
00121 }
00122 }
00123 dest[j++] = str[i++];
00124 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
00125 (format & DT_WORDBREAK))
00126 {
00127 if (!GetTextExtentPointW(hdc, &dest[j-1], 1, &size))
00128 return NULL;
00129 plen += size.cx;
00130 }
00131 break;
00132
00133 case TAB:
00134 if (format & DT_EXPANDTABS)
00135 {
00136 wb_i = ++i;
00137 wb_j = j;
00138 wb_count = *count;
00139
00140 if (!GetTextExtentPointW(hdc, &dest[lasttab], j - lasttab, &size))
00141 return NULL;
00142
00143 numspaces = (tabwidth - size.cx) / spacewidth;
00144 for (k = 0; k < numspaces; k++)
00145 dest[j++] = SPACE;
00146 plen += tabwidth - size.cx;
00147 lasttab = wb_j + numspaces;
00148 }
00149 else
00150 {
00151 dest[j++] = str[i++];
00152 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
00153 (format & DT_WORDBREAK))
00154 {
00155 if (!GetTextExtentPointW(hdc, &dest[j-1], 1, &size))
00156 return NULL;
00157 plen += size.cx;
00158 }
00159 }
00160 break;
00161
00162 case SPACE:
00163 dest[j++] = str[i++];
00164 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
00165 (format & DT_WORDBREAK))
00166 {
00167 wb_i = i;
00168 wb_j = j - 1;
00169 wb_count = *count;
00170 if (!GetTextExtentPointW(hdc, &dest[j-1], 1, &size))
00171 return NULL;
00172 plen += size.cx;
00173 }
00174 break;
00175
00176 default:
00177 dest[j++] = str[i++];
00178 if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
00179 (format & DT_WORDBREAK))
00180 {
00181 if (!GetTextExtentPointW(hdc, &dest[j-1], 1, &size))
00182 return NULL;
00183 plen += size.cx;
00184 }
00185 }
00186
00187 (*count)--;
00188 if (!(format & DT_NOCLIP) || (format & DT_WORDBREAK))
00189 {
00190 if (plen > width)
00191 {
00192 if (format & DT_WORDBREAK)
00193 {
00194 if (wb_j)
00195 {
00196 *len = wb_j;
00197 *count = wb_count - 1;
00198 return (&str[wb_i]);
00199 }
00200 }
00201 else
00202 {
00203 *len = j;
00204 return (&str[i]);
00205 }
00206 }
00207 }
00208 }
00209
00210 *len = j;
00211 return NULL;
00212 }
00213
00214
00215 #ifndef __WIN32OS2__
00216
00217
00218
00219 INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 count, LPRECT16 rect, UINT16 flags )
00220 {
00221 INT16 ret;
00222
00223 if (rect)
00224 {
00225 RECT rect32;
00226 CONV_RECT16TO32( rect, &rect32 );
00227 ret = DrawTextA( hdc, str, count, &rect32, flags );
00228 CONV_RECT32TO16( &rect32, rect );
00229 }
00230 else ret = DrawTextA( hdc, str, count, NULL, flags);
00231 return ret;
00232 }
00233 #endif
00234
00235
00236
00237
00238 #define MAX_STATIC_BUFFER 1024
00239 INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count,
00240 LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
00241 {
00242 SIZE size;
00243 const WCHAR *strPtr;
00244 static WCHAR line[MAX_STATIC_BUFFER];
00245 int len, lh, count=i_count;
00246 int prefix_x = 0;
00247 int prefix_end = 0;
00248 TEXTMETRICW tm;
00249 int lmargin = 0, rmargin = 0;
00250 int x = rect->left, y = rect->top;
00251 int width = rect->right - rect->left;
00252 int max_width = 0;
00253
00254 #ifdef __WIN32OS2__
00255 dprintf(("DrawTextExW: %ls, %d , [(%d,%d),(%d,%d)]\n", str, count,
00256 rect->left, rect->top, rect->right, rect->bottom));
00257 #else
00258 TRACE("%s, %d , [(%d,%d),(%d,%d)]\n", debugstr_wn (str, count), count,
00259 rect->left, rect->top, rect->right, rect->bottom);
00260 #endif
00261
00262 if (dtp) TRACE("Params: iTabLength=%d, iLeftMargin=%d, iRightMargin=%d\n",
00263 dtp->iTabLength, dtp->iLeftMargin, dtp->iRightMargin);
00264
00265 if (!str) return 0;
00266 if (count == -1) count = strlenW(str);
00267 if (count == 0) return 0;
00268 strPtr = str;
00269
00270 GetTextMetricsW(hdc, &tm);
00271 if (flags & DT_EXTERNALLEADING)
00272 lh = tm.tmHeight + tm.tmExternalLeading;
00273 else
00274 lh = tm.tmHeight;
00275
00276 if (dtp)
00277 {
00278 lmargin = dtp->iLeftMargin * tm.tmAveCharWidth;
00279 rmargin = dtp->iRightMargin * tm.tmAveCharWidth;
00280 if (!(flags & (DT_CENTER | DT_RIGHT)))
00281 x += lmargin;
00282 dtp->uiLengthDrawn = 0;
00283 }
00284
00285 if (flags & DT_TABSTOP)
00286 tabstop = dtp ? dtp->iTabLength : flags >> 8;
00287
00288 if (flags & DT_EXPANDTABS)
00289 {
00290 GetTextExtentPointW(hdc, SPACEW, 1, &size);
00291 spacewidth = size.cx;
00292 GetTextExtentPointW(hdc, oW, 1, &size);
00293 tabwidth = size.cx * tabstop;
00294 }
00295
00296 if (flags & DT_CALCRECT) flags |= DT_NOCLIP;
00297
00298 do
00299 {
00300 prefix_offset = -1;
00301 len = MAX_STATIC_BUFFER;
00302 strPtr = TEXT_NextLineW(hdc, strPtr, &count, line, &len, width, flags);
00303
00304 if (prefix_offset != -1)
00305 {
00306 GetTextExtentPointW(hdc, line, prefix_offset, &size);
00307 prefix_x = size.cx;
00308 GetTextExtentPointW(hdc, line, prefix_offset + 1, &size);
00309 prefix_end = size.cx - 1;
00310 }
00311
00312 if (!GetTextExtentPointW(hdc, line, len, &size)) return 0;
00313 if (flags & DT_CENTER) x = (rect->left + rect->right -
00314 size.cx) / 2;
00315 else if (flags & DT_RIGHT) x = rect->right - size.cx;
00316
00317 if (flags & DT_SINGLELINE)
00318 {
00319 if (flags & DT_VCENTER) y = rect->top +
00320 (rect->bottom - rect->top) / 2 - size.cy / 2;
00321 else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
00322
00323 if (flags & (DT_PATH_ELLIPSIS | DT_END_ELLIPSIS | DT_WORD_ELLIPSIS))
00324 {
00325 WCHAR swapStr[sizeof(line)];
00326 WCHAR* fnameDelim = NULL;
00327 int totalLen = i_count >= 0 ? i_count : strlenW(str);
00328
00329 if (size.cx > width)
00330 {
00331 int fnameLen = totalLen;
00332
00333
00334 count = min(totalLen+3, sizeof(line)-3);
00335
00336 if (flags & DT_WORD_ELLIPSIS)
00337 flags |= DT_WORDBREAK;
00338
00339 if (flags & DT_PATH_ELLIPSIS)
00340 {
00341 WCHAR* lastBkSlash = NULL;
00342 WCHAR* lastFwdSlash = NULL;
00343 strncpyW(line, str, totalLen);
00344 line[totalLen] = '\0';
00345 lastBkSlash = strrchrW(line, BACK_SLASHW[0]);
00346 lastFwdSlash = strrchrW(line, FORWARD_SLASHW[0]);
00347 fnameDelim = lastBkSlash > lastFwdSlash ? lastBkSlash : lastFwdSlash;
00348
00349 if (fnameDelim)
00350 fnameLen = &line[totalLen] - fnameDelim;
00351 else
00352 fnameDelim = (WCHAR*)str;
00353
00354 strcpyW(swapStr, ELLIPSISW);
00355 strncpyW(swapStr+strlenW(swapStr), fnameDelim, fnameLen);
00356 swapStr[fnameLen+3] = '\0';
00357 strncpyW(swapStr+strlenW(swapStr), str, totalLen - fnameLen);
00358 swapStr[totalLen+3] = '\0';
00359 }
00360 else
00361 {
00362 strcpyW(swapStr, ELLIPSISW);
00363 strncpyW(swapStr+strlenW(swapStr), str, totalLen);
00364 }
00365
00366 len = MAX_STATIC_BUFFER;
00367 TEXT_NextLineW(hdc, swapStr, &count, line, &len, width, flags);
00368
00369
00370 len = max(3, len);
00371 GetTextExtentPointW(hdc, line, len, &size);
00372
00373
00374
00375
00376
00377
00378
00379
00380 while ((size.cx > width) && (len > 3))
00381 {
00382 line[--len] = '\0';
00383 GetTextExtentPointW(hdc, line, len, &size);
00384 }
00385
00386 if (fnameLen < len-3)
00387 {
00388
00389 strncpyW(swapStr, &line[fnameLen+3], len-3-fnameLen);
00390 swapStr[len-3-fnameLen] = '\0';
00391 strcatW(swapStr, ELLIPSISW);
00392 strncpyW(swapStr+strlenW(swapStr), &line[3], fnameLen);
00393 }
00394 else
00395 {
00396
00397 strncpyW(swapStr, &line[3], len-3);
00398 swapStr[len-3] = '\0';
00399 strcpyW(swapStr+strlenW(swapStr), ELLIPSISW);
00400 }
00401
00402 strncpyW(line, swapStr, len);
00403 line[len] = '\0';
00404 strPtr = NULL;
00405 }
00406 if (flags & DT_MODIFYSTRING)
00407 strcpyW(str, swapStr);
00408 }
00409 }
00410 if (!(flags & DT_CALCRECT))
00411 {
00412 if (!ExtTextOutW( hdc, x, y,
00413 ((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) |
00414 ((flags & DT_RTLREADING) ? ETO_RTLREADING : 0),
00415 rect, line, len, NULL )) return 0;
00416 if (prefix_offset != -1)
00417 {
00418 HPEN hpen = CreatePen( PS_SOLID, 1, GetTextColor(hdc) );
00419 HPEN oldPen = SelectObject( hdc, hpen );
00420 MoveToEx(hdc, x + prefix_x, y + tm.tmAscent + 1, NULL );
00421 LineTo(hdc, x + prefix_end + 1, y + tm.tmAscent + 1 );
00422 SelectObject( hdc, oldPen );
00423 DeleteObject( hpen );
00424 }
00425 }
00426 else if (size.cx > max_width)
00427 max_width = size.cx;
00428
00429 y += lh;
00430 if (strPtr)
00431 {
00432 if (!(flags & DT_NOCLIP))
00433 {
00434 if (y > rect->bottom - lh)
00435 break;
00436 }
00437 }
00438 if (dtp)
00439 dtp->uiLengthDrawn += len;
00440 }
00441 while (strPtr);
00442
00443 if (flags & DT_CALCRECT)
00444 {
00445 rect->right = rect->left + max_width;
00446 rect->bottom = y;
00447 if (dtp)
00448 rect->right += lmargin + rmargin;
00449 }
00450 return y - rect->top;
00451 }
00452
00453
00454
00455
00456 INT WINAPI DrawTextExA( HDC hdc, LPCSTR str, INT count,
00457 LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
00458 {
00459 WCHAR *wstr;
00460 INT ret = 0;
00461 DWORD wcount;
00462
00463 if (count == -1) count = strlen(str);
00464 if (!count) return 0;
00465 wcount = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
00466 wstr = HeapAlloc(GetProcessHeap(), 0, wcount * sizeof(WCHAR));
00467 if (wstr)
00468 {
00469 MultiByteToWideChar( CP_ACP, 0, str, count, wstr, wcount );
00470 ret = DrawTextExW( hdc, wstr, wcount, rect, flags, NULL );
00471 if (flags & DT_MODIFYSTRING)
00472 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, count, NULL, NULL );
00473 HeapFree(GetProcessHeap(), 0, wstr);
00474 }
00475 return ret;
00476 }
00477
00478
00479
00480
00481 INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags )
00482 {
00483 return DrawTextExW(hdc, (LPWSTR)str, count, rect, flags, NULL);
00484 }
00485
00486
00487
00488
00489 INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags )
00490 {
00491 return DrawTextExA( hdc, (LPSTR)str, count, rect, flags, NULL );
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 static BOOL TEXT_GrayString(HDC hdc, HBRUSH hb, GRAYSTRINGPROC fn, LPARAM lp, INT len,
00505 INT x, INT y, INT cx, INT cy, BOOL unicode, BOOL _32bit)
00506 {
00507 HBITMAP hbm, hbmsave;
00508 HBRUSH hbsave;
00509 HFONT hfsave;
00510 HDC memdc = CreateCompatibleDC(hdc);
00511 int slen = len;
00512 BOOL retval = TRUE;
00513 COLORREF fg, bg;
00514
00515 #ifdef __WIN32OS2__
00516 dprintf(("GrayString %x %x %x %x %d (%d,%d)(%d,%d)", hdc, hb, fn, lp, len, x, y, cx, cy));
00517 if(!hdc) {
00518 DeleteDC(memdc);
00519 return FALSE;
00520 }
00521 #else
00522 if(!hdc) return FALSE;
00523 #endif
00524
00525 if(len == 0)
00526 {
00527 if(unicode)
00528 slen = lstrlenW((LPCWSTR)lp);
00529 else if(_32bit)
00530 slen = strlen((LPCSTR)lp);
00531 else
00532 slen = strlen(MapSL(lp));
00533 }
00534
00535 if((cx == 0 || cy == 0) && slen != -1)
00536 {
00537 SIZE s;
00538 if(unicode)
00539 GetTextExtentPoint32W(hdc, (LPCWSTR)lp, slen, &s);
00540 else if(_32bit)
00541 GetTextExtentPoint32A(hdc, (LPCSTR)lp, slen, &s);
00542 else
00543 GetTextExtentPoint32A(hdc, MapSL(lp), slen, &s);
00544 if(cx == 0) cx = s.cx;
00545 if(cy == 0) cy = s.cy;
00546 }
00547
00548 hbm = CreateBitmap(cx, cy, 1, 1, NULL);
00549 hbmsave = (HBITMAP)SelectObject(memdc, hbm);
00550 hbsave = SelectObject( memdc, GetStockObject(BLACK_BRUSH) );
00551 PatBlt( memdc, 0, 0, cx, cy, PATCOPY );
00552 SelectObject( memdc, hbsave );
00553 SetTextColor(memdc, RGB(255, 255, 255));
00554 SetBkColor(memdc, RGB(0, 0, 0));
00555 hfsave = (HFONT)SelectObject(memdc, GetCurrentObject(hdc, OBJ_FONT));
00556
00557 if(fn)
00558 {
00559 if(_32bit)
00560 retval = fn(memdc, lp, slen);
00561 else
00562 retval = (BOOL)((BOOL16)((GRAYSTRINGPROC16)fn)((HDC16)memdc, lp, (INT16)slen));
00563 }
00564 else
00565 {
00566 if(unicode)
00567 TextOutW(memdc, 0, 0, (LPCWSTR)lp, slen);
00568 else if(_32bit)
00569 TextOutA(memdc, 0, 0, (LPCSTR)lp, slen);
00570 else
00571 TextOutA(memdc, 0, 0, MapSL(lp), slen);
00572 }
00573
00574 SelectObject(memdc, hfsave);
00575
00576
00577
00578
00579
00580
00581 #ifdef GRAYSTRING_USING_DOCUMENTED_BEHAVIOUR
00582 if(retval || len != -1)
00583 #endif
00584 {
00585 hbsave = (HBRUSH)SelectObject(memdc, CACHE_GetPattern55AABrush());
00586 PatBlt(memdc, 0, 0, cx, cy, 0x000A0329);
00587 SelectObject(memdc, hbsave);
00588 }
00589
00590 if(hb) hbsave = (HBRUSH)SelectObject(hdc, hb);
00591 fg = SetTextColor(hdc, RGB(0, 0, 0));
00592 bg = SetBkColor(hdc, RGB(255, 255, 255));
00593 BitBlt(hdc, x, y, cx, cy, memdc, 0, 0, 0x00E20746);
00594 SetTextColor(hdc, fg);
00595 SetBkColor(hdc, bg);
00596 if(hb) SelectObject(hdc, hbsave);
00597
00598 SelectObject(memdc, hbmsave);
00599 DeleteObject(hbm);
00600 DeleteDC(memdc);
00601 return retval;
00602 }
00603
00604
00605 #ifndef __WIN32OS2__
00606
00607
00608
00609 BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
00610 LPARAM lParam, INT16 cch, INT16 x, INT16 y,
00611 INT16 cx, INT16 cy )
00612 {
00613 return TEXT_GrayString(hdc, hbr, (GRAYSTRINGPROC)gsprc, lParam, cch,
00614 x, y, cx, cy, FALSE, FALSE);
00615 }
00616 #endif
00617
00618
00619
00620
00621 BOOL WINAPI GrayStringA( HDC hdc, HBRUSH hbr, GRAYSTRINGPROC gsprc,
00622 LPARAM lParam, INT cch, INT x, INT y,
00623 INT cx, INT cy )
00624 {
00625 return TEXT_GrayString(hdc, hbr, gsprc, lParam, cch, x, y, cx, cy,
00626 FALSE, TRUE);
00627 }
00628
00629
00630
00631
00632
00633 BOOL WINAPI GrayStringW( HDC hdc, HBRUSH hbr, GRAYSTRINGPROC gsprc,
00634 LPARAM lParam, INT cch, INT x, INT y,
00635 INT cx, INT cy )
00636 {
00637 return TEXT_GrayString(hdc, hbr, gsprc, lParam, cch, x, y, cx, cy,
00638 TRUE, TRUE);
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648 static LONG TEXT_TabbedTextOut( HDC hdc, INT x, INT y, LPCSTR lpstr,
00649 INT count, INT cTabStops, const INT16 *lpTabPos16,
00650 const INT *lpTabPos32, INT nTabOrg,
00651 BOOL fDisplayText )
00652 {
00653 INT defWidth;
00654 SIZE extent;
00655 int i, tabPos = x;
00656 int start = x;
00657
00658 extent.cx = 0;
00659 extent.cy = 0;
00660
00661 if (cTabStops == 1)
00662 {
00663 defWidth = lpTabPos32 ? *lpTabPos32 : *lpTabPos16;
00664 cTabStops = 0;
00665 }
00666 else
00667 {
00668 TEXTMETRICA tm;
00669 GetTextMetricsA( hdc, &tm );
00670 defWidth = 8 * tm.tmAveCharWidth;
00671 }
00672
00673 while (count > 0)
00674 {
00675 for (i = 0; i < count; i++)
00676 if (lpstr[i] == '\t') break;
00677 GetTextExtentPointA( hdc, lpstr, i, &extent );
00678 if (lpTabPos32)
00679 {
00680 while ((cTabStops > 0) &&
00681 (nTabOrg + *lpTabPos32 <= x + extent.cx))
00682 {
00683 lpTabPos32++;
00684 cTabStops--;
00685 }
00686 }
00687 else
00688 {
00689 while ((cTabStops > 0) &&
00690 (nTabOrg + *lpTabPos16 <= x + extent.cx))
00691 {
00692 lpTabPos16++;
00693 cTabStops--;
00694 }
00695 }
00696 if (i == count)
00697 tabPos = x + extent.cx;
00698 else if (cTabStops > 0)
00699 tabPos = nTabOrg + (lpTabPos32 ? *lpTabPos32 : *lpTabPos16);
00700 else
00701 tabPos = nTabOrg + ((x + extent.cx - nTabOrg) / defWidth + 1) * defWidth;
00702 if (fDisplayText)
00703 {
00704 RECT r;
00705 r.left = x;
00706 r.top = y;
00707 r.right = tabPos;
00708 r.bottom = y + extent.cy;
00709 ExtTextOutA( hdc, x, y,
00710 GetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0,
00711 &r, lpstr, i, NULL );
00712 }
00713 x = tabPos;
00714 count -= i+1;
00715 lpstr += i+1;
00716 }
00717 return MAKELONG(tabPos - start, extent.cy);
00718 }
00719
00720
00721 #ifndef __WIN32OS2__
00722
00723
00724
00725 LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
00726 INT16 count, INT16 cTabStops,
00727 const INT16 *lpTabPos, INT16 nTabOrg )
00728 {
00729 TRACE("%04x %d,%d %s %d\n", hdc, x, y, debugstr_an(lpstr,count), count );
00730 return TEXT_TabbedTextOut( hdc, x, y, lpstr, count, cTabStops,
00731 lpTabPos, NULL, nTabOrg, TRUE );
00732 }
00733 #endif
00734
00735
00736
00737
00738 LONG WINAPI TabbedTextOutA( HDC hdc, INT x, INT y, LPCSTR lpstr, INT count,
00739 INT cTabStops, const INT *lpTabPos, INT nTabOrg )
00740 {
00741 #ifdef __WIN32OS2__
00742 dprintf(("TabbedTextOutA: %04x %d,%d %s %d\n", hdc, x, y, lpstr, count ));
00743 #else
00744 TRACE("%04x %d,%d %s %d\n", hdc, x, y, debugstr_an(lpstr,count), count );
00745 #endif
00746 return TEXT_TabbedTextOut( hdc, x, y, lpstr, count, cTabStops,
00747 NULL, lpTabPos, nTabOrg, TRUE );
00748 }
00749
00750
00751
00752
00753
00754 LONG WINAPI TabbedTextOutW( HDC hdc, INT x, INT y, LPCWSTR str, INT count,
00755 INT cTabStops, const INT *lpTabPos, INT nTabOrg )
00756 {
00757 LONG ret;
00758 LPSTR p;
00759 INT acount;
00760 UINT codepage = CP_ACP;
00761
00762 acount = WideCharToMultiByte(codepage,0,str,count,NULL,0,NULL,NULL);
00763 p = HeapAlloc( GetProcessHeap(), 0, acount );
00764 if(p == NULL) return 0;
00765 acount = WideCharToMultiByte(codepage,0,str,count,p,acount,NULL,NULL);
00766 ret = TabbedTextOutA( hdc, x, y, p, acount, cTabStops, lpTabPos, nTabOrg );
00767 HeapFree( GetProcessHeap(), 0, p );
00768 return ret;
00769 }
00770
00771
00772 #ifndef __WIN32OS2__
00773
00774
00775
00776 DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
00777 INT16 cTabStops, const INT16 *lpTabPos )
00778 {
00779 TRACE("%04x %s %d\n", hdc, debugstr_an(lpstr,count), count );
00780 return TEXT_TabbedTextOut( hdc, 0, 0, lpstr, count, cTabStops,
00781 lpTabPos, NULL, 0, FALSE );
00782 }
00783 #endif
00784
00785
00786
00787
00788 DWORD WINAPI GetTabbedTextExtentA( HDC hdc, LPCSTR lpstr, INT count,
00789 INT cTabStops, const INT *lpTabPos )
00790 {
00791 #ifdef __WIN32OS2__
00792 dprintf(("GetTabbedTextExtentA: %04x %s %d\n", hdc, lpstr, count ));
00793 #else
00794 TRACE("%04x %s %d\n", hdc, debugstr_an(lpstr,count), count );
00795 #endif
00796 return TEXT_TabbedTextOut( hdc, 0, 0, lpstr, count, cTabStops,
00797 NULL, lpTabPos, 0, FALSE );
00798 }
00799
00800
00801
00802
00803
00804 DWORD WINAPI GetTabbedTextExtentW( HDC hdc, LPCWSTR lpstr, INT count,
00805 INT cTabStops, const INT *lpTabPos )
00806 {
00807 LONG ret;
00808 LPSTR p;
00809 INT acount;
00810 UINT codepage = CP_ACP;
00811
00812 acount = WideCharToMultiByte(codepage,0,lpstr,count,NULL,0,NULL,NULL);
00813 p = HeapAlloc( GetProcessHeap(), 0, acount );
00814 if(p == NULL) return 0;
00815 acount = WideCharToMultiByte(codepage,0,lpstr,count,p,acount,NULL,NULL);
00816 ret = GetTabbedTextExtentA( hdc, p, acount, cTabStops, lpTabPos );
00817 HeapFree( GetProcessHeap(), 0, p );
00818 return ret;
00819 }