00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
00015 #define CR 13
00016 #define LF 10
00017
00018 #define DT_HFMTMASK 0x03
00019
00020
00021
00022
00023
00024
00025
00026
00027 BOOL IsMetaFile(
00028 HDC hdc)
00029 {
00030
DWORD dwType = GetObjectType(hdc);
00031
return (dwType == OBJ_METAFILE ||
00032 dwType == OBJ_METADC ||
00033 dwType == OBJ_ENHMETAFILE ||
00034 dwType == OBJ_ENHMETADC);
00035 }
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 CONST WCHAR
gwszNullStr[] =
L"";
00046
00047 int DrawTextExA(
00048 HDC hdc,
00049 LPSTR lpchText,
00050
int cchText,
00051 LPRECT lprc,
00052 UINT format,
00053 LPDRAWTEXTPARAMS lpdtp)
00054 {
00055 LPWSTR lpwstr;
00056
int iRet;
00057
int iUniString;
00058 WORD wCodePage = (WORD)GdiGetCodePage(hdc);
00059
00060
if (cchText == -1) {
00061
00062 cchText = USER_AWCONV_COUNTSTRINGSZ;
00063 }
else if (cchText < -1) {
00064
return 0;
00065 }
00066
00067
if ((iUniString =
MBToWCSEx(wCodePage, lpchText, cchText, &lpwstr, -1,
TRUE)) == 0) {
00068
if (cchText == USER_AWCONV_COUNTSTRINGSZ) {
00069 lpwstr = (LPWSTR)
gwszNullStr;
00070
format &= ~DT_MODIFYSTRING;
00071 }
else {
00072
return 0;
00073 }
00074 }
00075
00076
00077
00078
00079
if (
format & DT_MODIFYSTRING) {
00080
int iNewLen = (iUniString +
CCHELLIPSIS + 1) *
sizeof(*lpwstr);
00081 LPWSTR lpwstrNew =
UserLocalReAlloc(lpwstr, iNewLen, HEAP_ZERO_MEMORY);
00082
if (lpwstrNew ==
NULL) {
00083
UserLocalFree((HANDLE)lpwstr);
00084
return FALSE;
00085 }
00086 lpwstr = lpwstrNew;
00087 }
00088
00089 iRet =
DrawTextExWorker(hdc, lpwstr, iUniString, lprc,
format, lpdtp, GetTextCharset(hdc));
00090
00091
if (
format & DT_MODIFYSTRING) {
00092
00093
00094
00095
00096
00097
if (cchText < 0) {
00098 UserAssert(cchText == USER_AWCONV_COUNTSTRINGSZ);
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
if (
IS_DBCS_ENABLED()) {
00109 cchText = iUniString *
DBCS_CHARSIZE;
00110 }
else {
00111 cchText = iUniString *
sizeof(
CHAR);
00112 }
00113 }
00114 WCSToMBEx(wCodePage, lpwstr, iUniString, &lpchText, cchText,
FALSE);
00115 }
00116
00117
if (lpwstr !=
gwszNullStr) {
00118
UserLocalFree((HANDLE)lpwstr);
00119 }
00120
00121
return iRet;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131 int DrawTextW(
00132 HDC hdc,
00133 LPCWSTR lpchText,
00134
int cchText,
00135 LPRECT lprc,
00136 UINT format)
00137 {
00138 DRAWTEXTPARAMS DTparams;
00139 LPDRAWTEXTPARAMS lpDTparams =
NULL;
00140
00141
00142
00143
00144
if (cchText < -1)
00145
return(0);
00146
00147
if (
format & DT_TABSTOP)
00148 {
00149 DTparams.cbSize =
sizeof(DRAWTEXTPARAMS);
00150 DTparams.iLeftMargin = DTparams.iRightMargin = 0;
00151 DTparams.iTabLength = (
format & 0xff00) >> 8;
00152 lpDTparams = &DTparams;
00153
format &= 0xffff00ff;
00154 }
00155
00156
return DrawTextExW(hdc, (LPWSTR)lpchText, cchText, lprc,
format, lpDTparams);
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166 int DrawTextA(
00167 HDC hdc,
00168 LPCSTR lpchText,
00169
int cchText,
00170 LPRECT lprc,
00171 UINT format)
00172 {
00173 DRAWTEXTPARAMS DTparams;
00174 LPDRAWTEXTPARAMS lpDTparams =
NULL;
00175
00176
00177
00178
00179
if (cchText < -1)
00180
return(0);
00181
00182
if (
format & DT_TABSTOP) {
00183 DTparams.cbSize =
sizeof(DRAWTEXTPARAMS);
00184 DTparams.iLeftMargin = DTparams.iRightMargin = 0;
00185 DTparams.iTabLength = (
format & 0xff00) >> 8;
00186 lpDTparams = &DTparams;
00187
format &= 0xffff00ff;
00188 }
00189
00190
return DrawTextExA(hdc, (LPSTR)lpchText, cchText, lprc,
format, lpDTparams);
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 LONG
TabTextOut(
00213 HDC hdc,
00214
int x,
00215
int y,
00216 LPCWSTR lpstring,
00217
int nCount,
00218
int nTabPositions,
00219 CONST INT *lpTabPositions,
00220
int iTabOrigin,
00221 BOOL fDrawTheText,
00222
int iCharset)
00223 {
00224
int cxCharWidth;
00225
int cyCharHeight = 0;
00226
00227
if (nCount == -1 && lpstring) {
00228 nCount = wcslen(lpstring);
00229 }
00230
if (!lpstring || nCount < 0 || nTabPositions < 0)
00231
return 0;
00232
00233
00234
00235
00236
if (
IsSysFontAndDefaultMode(hdc))
00237 {
00238 cxCharWidth =
gpsi->cxSysFontChar;
00239 cyCharHeight =
gpsi->cySysFontChar;
00240 }
else {
00241 cxCharWidth = GdiGetCharDimensions(hdc,
NULL, &cyCharHeight);
00242
if (cxCharWidth == 0) {
00243 RIPMSG0(RIP_WARNING,
"TabTextOut: GdiGetCharDimensions failed");
00244
return 0;
00245 }
00246 }
00247
00248
return (*fpLpkTabbedTextOut)(hdc, x, y, lpstring, nCount, nTabPositions,
00249 lpTabPositions, iTabOrigin, fDrawTheText,
00250 cxCharWidth, cyCharHeight, iCharset);
00251 }
00252
00253 LONG
UserLpkTabbedTextOut(
00254 HDC hdc,
00255
int x,
00256
int y,
00257 LPCWSTR lpstring,
00258
int nCount,
00259
int nTabPositions,
00260 CONST INT *lpTabPositions,
00261
int iTabOrigin,
00262 BOOL fDrawTheText,
00263
int cxCharWidth,
00264
int cyCharHeight,
00265
int iCharset)
00266 {
00267 SIZE textextent, viewextent, windowextent;
00268
int initialx = x;
00269
int cch;
00270 LPCWSTR lp;
00271
int iOneTab = 0;
00272 RECT rc;
00273
UINT uOpaque = (GetBkMode(hdc) == OPAQUE) ? ETO_OPAQUE : 0;
00274
BOOL fStrStart =
TRUE;
00275
int ySign = 1;
00276
00277 UNREFERENCED_PARAMETER(iCharset);
00278
00279
00280
00281
00282
if (!lpTabPositions) {
00283
00284 iOneTab = 8 * cxCharWidth;
00285 }
else if (nTabPositions == 1) {
00286
00287
00288 iOneTab = lpTabPositions[0];
00289
00290
if (!iOneTab)
00291 iOneTab = 1;
00292 }
00293
00294
00295
00296
00297
if (!GetViewportExtEx(hdc, &viewextent))
00298
return 0;
00299 GetWindowExtEx(hdc, &windowextent);
00300
if ((viewextent.cy ^ windowextent.cy) & 0x80000000)
00301 ySign = -1;
00302
00303 rc.left = initialx;
00304 rc.top = y;
00305 rc.bottom = rc.top + (ySign * cyCharHeight);
00306
00307
while (
TRUE) {
00308
00309
00310
00311
for (cch = nCount, lp = lpstring; cch && (*lp != TEXT(
'\t')); lp++, cch--)
00312 {
00313 }
00314
00315
00316 cch = nCount - cch;
00317
00318
00319 nCount -= cch + 1;
00320
00321
00322
if (cch == 0) {
00323 textextent.cx = 0;
00324 textextent.cy = cyCharHeight;
00325 }
else
00326 GetTextExtentPointW(hdc, lpstring, cch, &textextent);
00327
00328
if (fStrStart)
00329
00330
00331 fStrStart =
FALSE;
00332
else
00333 {
00334
00335
00336
int xTab;
00337
int i;
00338
00339
if (!iOneTab)
00340 {
00341
00342
00343
for (i = 0; i < nTabPositions; i++)
00344 {
00345 xTab = lpTabPositions[i];
00346
00347
if (xTab < 0)
00348
00349 xTab = (iTabOrigin - xTab) - textextent.cx;
00350
else
00351
00352 xTab = iTabOrigin + xTab;
00353
00354
if (x < xTab)
00355 {
00356
00357 x = xTab;
00358
break;
00359 }
00360 }
00361
00362
if (i == nTabPositions)
00363
00364
00365 iOneTab = 8 * cxCharWidth;
00366 }
00367
00368
00369
00370
if (iOneTab)
00371 {
00372
if (iOneTab < 0)
00373 {
00374
00375 xTab = x + textextent.cx - iTabOrigin;
00376 xTab = ((xTab / iOneTab) * iOneTab) - iOneTab - textextent.cx + iTabOrigin;
00377 }
00378
else
00379 {
00380
00381 xTab = x - iTabOrigin;
00382 xTab = ((xTab / iOneTab) * iOneTab) + iOneTab + iTabOrigin;
00383 }
00384 x = xTab;
00385 }
00386 }
00387
00388
if (fDrawTheText) {
00389
00390
00391
00392
00393
00394 rc.right = x + textextent.cx;
00395 ExtTextOutW(
00396 hdc, x, y, uOpaque, &rc, (LPWSTR)lpstring,
00397 cch,
NULL);
00398 rc.left = rc.right;
00399 }
00400
00401
00402 x += textextent.cx;
00403
00404
00405 lpstring += cch;
00406
00407
00408
00409
if((nCount > 0) || ((nCount == 0) && (*lpstring == TEXT(
'\t'))))
00410 {
00411
00412 lpstring++;
00413
continue;
00414 }
00415
else
00416
break;
00417 }
00418
return MAKELONG((x - initialx), (
short)textextent.cy);
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 LONG
TabbedTextOutW(
00439 HDC hdc,
00440
int x,
00441
int y,
00442 LPCWSTR lpstring,
00443
int cchChars,
00444
int nTabPositions,
00445 CONST INT *lpintTabStopPositions,
00446
int iTabOrigin)
00447 {
00448
return TabTextOut(hdc, x, y, lpstring, cchChars,
00449 nTabPositions, lpintTabStopPositions, iTabOrigin,
TRUE, -1);
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459 LONG
TabbedTextOutA(
00460 HDC hdc,
00461
int x,
00462
int y,
00463 LPCSTR pString,
00464
int chCount,
00465
int nTabPositions,
00466 CONST INT *pnTabStopPositions,
00467
int nTabOrigin)
00468 {
00469 LPWSTR lpwstr;
00470
BOOL bRet;
00471 WORD wCodePage = (WORD)GdiGetCodePage(hdc);
00472
int iUniString;
00473
00474
if (chCount == -1) {
00475 chCount = USER_AWCONV_COUNTSTRINGSZ;
00476 }
00477
00478
if ((iUniString =
MBToWCSEx(wCodePage, pString, chCount, &lpwstr, -1,
TRUE)) == 0) {
00479
if (chCount == USER_AWCONV_COUNTSTRINGSZ) {
00480 lpwstr = (LPWSTR)
gwszNullStr;
00481 }
else {
00482
return FALSE;
00483 }
00484 }
00485
00486 bRet =
TabTextOut(
00487 hdc, x, y, lpwstr, iUniString, nTabPositions,
00488 pnTabStopPositions, nTabOrigin,
TRUE, GetTextCharset(hdc));
00489
00490
if (lpwstr !=
gwszNullStr) {
00491
UserLocalFree((HANDLE)lpwstr);
00492 }
00493
00494
return bRet;
00495 }
00496
00497 DWORD GetTabbedTextExtentW(
00498 HDC hdc,
00499 LPCWSTR pString,
00500
int chCount,
00501
int nTabPositions,
00502 CONST INT *pnTabStopPositions)
00503 {
00504
return TabTextOut(hdc, 0, 0, pString, chCount,
00505 nTabPositions, pnTabStopPositions, 0,
FALSE, -1);
00506 }
00507
00508 DWORD GetTabbedTextExtentA(
00509 HDC hdc,
00510 LPCSTR pString,
00511
int chCount,
00512
int nTabPositions,
00513 CONST INT *pnTabStopPositions)
00514 {
00515 LPWSTR lpwstr;
00516
BOOL bRet;
00517 WORD wCodePage = (WORD)GdiGetCodePage(hdc);
00518
int iUniString;
00519
00520
if (chCount == -1) {
00521 chCount = USER_AWCONV_COUNTSTRINGSZ;
00522 }
00523
if ((iUniString =
MBToWCSEx(wCodePage, pString, chCount, &lpwstr, -1,
TRUE)) == 0) {
00524
if (chCount == USER_AWCONV_COUNTSTRINGSZ) {
00525 lpwstr = (LPWSTR)
gwszNullStr;
00526 }
else {
00527
return FALSE;
00528 }
00529 }
00530
00531 bRet =
TabTextOut(hdc, 0, 0, lpwstr, iUniString,
00532 nTabPositions, pnTabStopPositions, 0,
FALSE, GetTextCharset(hdc));
00533
00534
if (lpwstr !=
gwszNullStr) {
00535
UserLocalFree((HANDLE)lpwstr);
00536 }
00537
00538
return bRet;
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 void PSMTextOut(
00556 HDC hdc,
00557
int xLeft,
00558
int yTop,
00559 LPWSTR lpsz,
00560
int cch,
00561 DWORD dwFlags)
00562 {
00563
00564
00565
00566
00567
00568 (*fpLpkPSMTextOut)(hdc, xLeft, yTop, lpsz, cch,
dwFlags);
00569
return;
00570 }
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 void UserLpkPSMTextOut(
00581 HDC hdc,
00582
int xLeft,
00583
int yTop,
00584 LPWSTR lpsz,
00585
int cch,
00586 DWORD dwFlags)
00587 {
00588
int cx;
00589 LONG textsize, result;
00590 WCHAR achWorkBuffer[255];
00591 WCHAR *pchOut = achWorkBuffer;
00592 TEXTMETRICW textMetric;
00593 SIZE size;
00594 RECT rc;
00595 COLORREF color;
00596
00597
if (cch >
sizeof(achWorkBuffer)/
sizeof(WCHAR)) {
00598 pchOut = (WCHAR*)
UserLocalAlloc(HEAP_ZERO_MEMORY, (cch+1) *
sizeof(WCHAR));
00599
if (pchOut ==
NULL)
00600
return;
00601 }
00602
00603 result =
GetPrefixCount(lpsz, cch, pchOut, cch);
00604
00605
00606
00607
00608
if (!(
dwFlags & DT_PREFIXONLY)) {
00609 TextOutW(hdc, xLeft, yTop, pchOut, cch - HIWORD(result));
00610 }
00611
00612
00613
00614
00615
if (LOWORD(result) == 0xFFFF ||
dwFlags & DT_HIDEPREFIX) {
00616
if (pchOut != achWorkBuffer)
00617
UserLocalFree(pchOut);
00618
return;
00619 }
00620
00621
if (!GetTextMetricsW(hdc, &textMetric)) {
00622 textMetric.tmOverhang = 0;
00623 textMetric.tmAscent = 0;
00624 }
00625
00626
00627
00628
00629
if (LOWORD(result) != 0) {
00630
00631
00632
00633
00634 GetTextExtentPointW(hdc, pchOut, LOWORD(result), &size);
00635 xLeft += size.cx;
00636
00637
00638
00639
00640
00641 xLeft = xLeft - textMetric.tmOverhang;
00642 }
00643
00644
00645
00646
00647
00648 GetTextExtentPointW(hdc, pchOut + LOWORD(result), 1, &size);
00649 textsize = size.cx;
00650
00651
00652
00653
00654
00655
00656 cx = LOWORD(textsize) - textMetric.tmOverhang / 2;
00657
00658
00659
00660
00661 yTop += textMetric.tmAscent + 1;
00662
00663
00664
00665
00666
SetRect(&rc, xLeft, yTop, xLeft+cx, yTop+1);
00667 color = SetBkColor(hdc, GetTextColor(hdc));
00668 ExtTextOutW(hdc, xLeft, yTop, ETO_OPAQUE, &rc, TEXT(
""), 0,
NULL);
00669 SetBkColor(hdc, color);
00670
00671
if (pchOut != achWorkBuffer) {
00672
UserLocalFree(pchOut);
00673 }
00674 }