Changeset 10374 for trunk/src/gdi32/text.cpp
- Timestamp:
- Jan 11, 2004, 12:43:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gdi32/text.cpp
r10368 r10374 1 /* $Id: text.cpp,v 1. 39 2003-12-29 12:04:15sandervl Exp $ */1 /* $Id: text.cpp,v 1.40 2004-01-11 11:42:22 sandervl Exp $ */ 2 2 3 3 /* 4 4 * GDI32 text apis 5 5 * 6 * Based on Wine code (991031) (objects\text.c)6 * Based on Wine/ReWind code (objects\text.c, objects\font.c) 7 7 * 8 8 * Copyright 1993, 1994 Alexandre Julliard 9 * 1997 Alex Korobka 10 * 9 11 * Copyright 1999-2000 Christoph Bratschi 12 * Copyright 2002-2003 Innotek Systemberatung GmbH (sandervl@innotek.de) 10 13 * 11 14 * Project Odin Software License can be found in LICENSE.TXT … … 21 24 #include <dcdata.h> 22 25 #include <unicode.h> 26 #include "dibsect.h" 27 #include "ft2supp.h" 23 28 #include "font.h" 24 29 … … 77 82 //#define INVERT_SETYINVERSION 78 83 //****************************************************************************** 79 BOOL InternalTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut) 84 BOOL InternalTextOutAW(HDC hdc,int X,int Y,UINT fuOptions, 85 CONST RECT *lprc, LPCSTR lpszStringA, LPCWSTR lpszStringW, 86 INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut, BOOL fUnicode) 80 87 { 81 88 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc); … … 85 92 LONG hits; 86 93 87 if (!pHps || (cbCount < 0) || (( lpszString == NULL) && (cbCount != 0)))94 if (!pHps || (cbCount < 0) || (((lpszStringA == NULL && !fUnicode) || (lpszStringW == NULL && fUnicode)) && (cbCount != 0))) 88 95 { 89 96 dprintf(("InternalTextOutA: invalid parameter")); … … 92 99 } 93 100 101 if(cbCount == -1) { 102 if(fUnicode) 103 cbCount = lstrlenW(lpszStringW); 104 else cbCount = lstrlenA(lpszStringA); 105 } 106 94 107 if (cbCount > 512) 95 108 { … … 98 111 return FALSE; 99 112 } 100 if (fuOptions & ~((UINT)(ETO_CLIPPED | ETO_OPAQUE )))113 if (fuOptions & ~((UINT)(ETO_CLIPPED | ETO_OPAQUE | ETO_GLYPH_INDEX))) 101 114 { 102 115 dprintf(("InternalTextOutA: invalid fuOptions")); … … 150 163 else 151 164 { 152 if (fuOptions )153 { 154 dprintf(("InternalTextOutA: ERROR_INVALID_ HANDLE"));155 SetLastError(ERROR_INVALID_ HANDLE);165 if (fuOptions & ~ETO_GLYPH_INDEX) 166 { 167 dprintf(("InternalTextOutA: ERROR_INVALID_PARAMETER")); 168 SetLastError(ERROR_INVALID_PARAMETER); 156 169 return FALSE; 157 170 } 171 } 172 173 if((lpszStringA || lpszStringW) && cbCount) { 174 DIBSECTION_CHECK_IF_DIRTY(hdc); 158 175 } 159 176 … … 176 193 SelectObject(hdc, oldbrush); 177 194 DeleteObject(hbrush); 195 196 DIBSECTION_MARK_INVALID(hdc); 197 178 198 return TRUE; 179 199 #endif … … 244 264 #endif 245 265 246 hits = OSLibGpiCharStringPosAt(pHps,&ptl,&pmRect,flOptions,cbCount,lpszString,lpDx); 266 if(fUnicode) 267 hits = FT2Module.Ft2CharStringPosAtW(pHps->hps,&ptl,&pmRect,flOptions,cbCount,lpszStringW,lpDx, fuOptions & ETO_GLYPH_INDEX); 268 else hits = FT2Module.Ft2CharStringPosAtA(pHps->hps,&ptl,&pmRect,flOptions,cbCount,lpszStringA,lpDx, fuOptions & ETO_GLYPH_INDEX); 247 269 248 270 if (lprc && ((align & 0x18) == TA_BASELINE)) 249 OSLibGpiSetTextAlignment(pHps,pmHAlign,pmVAlign);271 OSLibGpiSetTextAlignment(pHps,pmHAlign,pmVAlign); 250 272 251 273 if(hits == GPIOS_ERROR) { 252 274 dprintf(("InternalTextOutA: OSLibGpiCharStringPosAt returned GPIOS_ERROR")); 253 275 #ifdef INVERT_SETYINVERSION 254 255 #endif 256 276 GpiEnableYInversion(pHps->hps, oldyinv); 277 #endif 278 return FALSE; 257 279 } 258 280 259 281 if (getAlignUpdateCP(pHps)) 260 282 { 261 OSLibGpiQueryCurrentPosition(pHps,&ptl);262 ptl.y -= getWorldYDeltaFor1Pixel(pHps);283 OSLibGpiQueryCurrentPosition(pHps,&ptl); 284 ptl.y -= getWorldYDeltaFor1Pixel(pHps); 263 285 #ifndef INVERT 264 ptl.y += vertAdjust;265 #endif 266 OSLibGpiSetCurrentPosition(pHps,&ptl);286 ptl.y += vertAdjust; 287 #endif 288 OSLibGpiSetCurrentPosition(pHps,&ptl); 267 289 } 268 290 … … 270 292 GpiEnableYInversion(pHps->hps, oldyinv); 271 293 #endif 294 295 DIBSECTION_MARK_INVALID(hdc); 296 272 297 return TRUE; 273 298 } 274 299 //****************************************************************************** 275 300 //****************************************************************************** 276 BOOL InternalTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCWSTR lpszString,INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut) 277 { 278 char *astring = NULL; 301 BOOL WIN32API ExtTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,UINT cbCount,CONST INT *lpDx) 302 { 279 303 BOOL rc; 280 281 if(cbCount == -1) { 282 astring = UnicodeToAsciiString((LPWSTR)lpszString); 283 } 284 else 285 if(cbCount >= 0) { 286 int n = WideCharToMultiByte( CP_ACP, 0, lpszString, cbCount, 0, 0, NULL, NULL ) + 1; 287 288 astring = (char *)HEAP_malloc( n ); 289 UnicodeToAsciiN((LPWSTR)lpszString, astring, n ); 290 } 291 292 rc = InternalTextOutA(hdc,X,Y,fuOptions,lprc,(LPCSTR)astring, strlen( astring ),lpDx,IsExtTextOut); 293 if(astring) { 294 FreeAsciiString(astring); 295 } 304 SIZE size; 305 int newy; 306 307 if(lprc) 308 { 309 dprintf(("GDI32: ExtTextOutA %x %.*s (%d,%d) %x %d %x rect (%d,%d)(%d,%d)", hdc, cbCount, lpszString, X, Y, fuOptions, cbCount, lpDx, lprc->left, lprc->top, lprc->right, lprc->bottom)); 310 } 311 else dprintf(("GDI32: ExtTextOutA %x %.*s (%d,%d) %x %d %x", hdc, cbCount, lpszString, X, Y, fuOptions, cbCount, lpDx)); 312 313 rc = InternalTextOutAW(hdc, X, Y, fuOptions, lprc, lpszString, NULL, cbCount, lpDx, TRUE, FALSE); 296 314 297 315 return(rc); … … 299 317 //****************************************************************************** 300 318 //****************************************************************************** 301 BOOL WIN32API ExtTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,UINT cbCount,CONST INT *lpDx)302 {303 LPSTR astring = NULL;304 LPCSTR aCstring = lpszString;305 BOOL rc;306 307 /* no guarantee for zeroterminated text in lpszString, found in "PuTTY A Free Win32 Telnet SSH Client" */308 if (cbCount >= 0)309 {310 astring = (char *)malloc(cbCount+1);311 memcpy(astring, lpszString, cbCount);312 astring[cbCount] = '\0';313 aCstring = astring;314 }315 if(lprc)316 {317 dprintf(("GDI32: ExtTextOutA %x %s (%d,%d) %x %d %x rect (%d,%d)(%d,%d)", hdc, /*lpszString*/ aCstring, X, Y, fuOptions, cbCount, lpDx, lprc->left, lprc->top, lprc->right, lprc->bottom));318 }319 else dprintf(("GDI32: ExtTextOutA %x %s (%d,%d) %x %d %x", hdc, /*lpszString*/ aCstring, X, Y, fuOptions, cbCount, lpDx));320 321 rc = InternalTextOutA(hdc, X, Y, fuOptions, lprc, aCstring, cbCount, lpDx, TRUE);322 323 if(astring)324 free(astring);325 326 return(rc);327 }328 //******************************************************************************329 //******************************************************************************330 319 BOOL WIN32API ExtTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCWSTR lpszString,UINT cbCount,CONST int *lpDx) 331 320 { 332 321 if(lprc) { 333 dprintf(("GDI32: ExtTextOutW %x %ls (%d,%d) %x %d %x rect (%d,%d)(%d,%d)", hdc, lpszString, X, Y, fuOptions, cbCount, lpDx, lprc->left, lprc->top, lprc->right, lprc->bottom)); 334 } 335 else dprintf(("GDI32: ExtTextOutW %x %ls (%d,%d) %x %d %x", hdc, lpszString, X, Y, fuOptions, cbCount, lpDx)); 336 return InternalTextOutW(hdc, X, Y, fuOptions, lprc, lpszString, cbCount, lpDx, TRUE); 322 dprintf(("GDI32: ExtTextOutW %x %.*ls (%d,%d) %x %d %x rect (%d,%d)(%d,%d)", hdc, cbCount, lpszString, X, Y, fuOptions, cbCount, lpDx, lprc->left, lprc->top, lprc->right, lprc->bottom)); 323 } 324 else dprintf(("GDI32: ExtTextOutW %x %.*ls (%d,%d) %x %d %x", hdc, cbCount, lpszString, X, Y, fuOptions, cbCount, lpDx)); 325 326 return InternalTextOutAW(hdc, X, Y, fuOptions, lprc, NULL, lpszString, cbCount, lpDx, TRUE, TRUE); 337 327 } 338 328 //****************************************************************************** … … 341 331 { 342 332 dprintf(("GDI32: TextOutA %x (%d,%d) %d %.*s", hdc, nXStart, nYStart, cbString, cbString, lpszString)); 343 return InternalTextOutA (hdc,nXStart,nYStart,0,NULL,lpszString,cbString,NULL,FALSE);333 return InternalTextOutAW(hdc,nXStart,nYStart,0,NULL,lpszString,NULL,cbString,NULL,FALSE, FALSE); 344 334 } 345 335 //****************************************************************************** … … 348 338 { 349 339 dprintf(("GDI32: TextOutW %x (%d,%d) %d %.*ls", hdc, nXStart, nYStart, cbString, cbString, lpszString)); 350 return InternalTextOut W(hdc,nXStart,nYStart,0,NULL,lpszString,cbString,NULL,FALSE);340 return InternalTextOutAW(hdc,nXStart,nYStart,0,NULL, NULL, lpszString,cbString,NULL,FALSE, TRUE); 351 341 } 352 342 //****************************************************************************** … … 358 348 for (INT x = 0;x < cStrings;x++) 359 349 { 360 BOOL rc;361 362 rc = InternalTextOutA(hdc,pptxt[x].x,pptxt[x].y,pptxt[x].uiFlags,&pptxt[x].rcl,pptxt[x].lpstr,pptxt[x].n,pptxt[x].pdx,TRUE);363 if (!rc) return FALSE;350 BOOL rc; 351 352 rc = ExtTextOutA(hdc,pptxt[x].x,pptxt[x].y,pptxt[x].uiFlags,&pptxt[x].rcl,pptxt[x].lpstr, pptxt[x].n,pptxt[x].pdx); 353 if (!rc) return FALSE; 364 354 } 365 355 … … 374 364 for (INT x = 0;x < cStrings;x++) 375 365 { 376 BOOL rc;377 378 rc = InternalTextOutW(hdc,pptxt[x].x,pptxt[x].y,pptxt[x].uiFlags,&pptxt[x].rcl,pptxt[x].lpstr,pptxt[x].n,pptxt[x].pdx,TRUE);379 if (!rc) return FALSE;366 BOOL rc; 367 368 rc = ExtTextOutW(hdc,pptxt[x].x,pptxt[x].y,pptxt[x].uiFlags,&pptxt[x].rcl, pptxt[x].lpstr,pptxt[x].n,pptxt[x].pdx); 369 if (!rc) return FALSE; 380 370 } 381 371 … … 383 373 } 384 374 //****************************************************************************** 375 // Note: GetTextExtentPoint behaves differently under certain circumstances 376 // compared to GetTextExtentPoint32 (due to bugs). 377 // We are treating both as the same thing which is not entirely correct. 378 // 385 379 //****************************************************************************** 386 380 BOOL WIN32API GetTextExtentPointA(HDC hdc, LPCTSTR lpsz, int cbString, … … 428 422 if(cbString == 0) 429 423 { 424 dprintf(("!WARNING!: GDI32: GetTextExtentPointW invalid parameter!")); 430 425 SetLastError(ERROR_SUCCESS); 431 426 return TRUE; 432 427 } 428 429 if(pHps->isPrinter) 430 ReallySetCharAttrs(pHps); 431 433 432 if(cbString > 512) 434 433 { … … 447 446 lpSize->cx += newSize.cx; 448 447 lpSize->cy = max(newSize.cy, lpSize->cy); 449 lpString 448 lpString += cbStringNew; 450 449 cbString -= cbStringNew; 451 450 } … … 453 452 } 454 453 455 int len; 456 LPSTR astring; 457 458 len = WideCharToMultiByte( CP_ACP, 0, lpString, cbString, 0, 0, NULL, NULL ); 459 astring = (char *)malloc( len + 1 ); 460 lstrcpynWtoA(astring, lpString, len + 1 ); 461 462 rc = OSLibGpiQueryTextBox(pHps, len, astring, TXTBOXOS_COUNT, pts); 463 free(astring); 464 454 rc = FT2Module.Ft2GetTextExtentW(pHps->hps, cbString, lpString, TXTBOXOS_COUNT, pts); 465 455 if(rc == FALSE) 466 456 { … … 476 466 LONG alArray[2]; 477 467 478 if 479 lpSize->cx = lpSize->cx * alArray[0] / alArray[1];468 if(OSLibDevQueryCaps(pHps, OSLIB_CAPS_HORIZONTAL_RESOLUTION, 2, &alArray[0])) 469 lpSize->cx = lpSize->cx * alArray[0] / alArray[1]; 480 470 } 481 471 … … 553 543 for(index = 0; index < count; index++) 554 544 { 555 545 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done; 556 546 /* GetTextExtentPoint includes intercharacter spacing. */ 557 547 /* FIXME - justification needs doing yet. Remember that the base 558 548 * data will not be in logical coordinates. 559 549 */ 560 561 550 extent += tSize.cx; 551 if( !lpnFit || extent <= maxExt ) 562 552 /* It is allowed to be equal. */ 563 553 { 564 565 554 nFit++; 555 if( alpDx ) alpDx[index] = extent; 566 556 } 567 568 557 if( tSize.cy > size->cy ) size->cy = tSize.cy; 558 str++; 569 559 } 570 560 size->cx = extent; … … 579 569 //****************************************************************************** 580 570 //****************************************************************************** 571 BOOL WIN32API GetCharWidth32A( HDC hdc, UINT iFirstChar, UINT iLastChar, PINT pWidthArray) 572 { 573 BOOL ret = FALSE; 574 575 for (int i = iFirstChar; i <= iLastChar; i++) 576 { 577 SIZE size; 578 CHAR c = i; 579 580 if (GetTextExtentPointA(hdc, &c, 1, &size)) 581 { 582 pWidthArray[i-iFirstChar] = size.cx; 583 // at least one character was processed 584 ret = TRUE; 585 } 586 else 587 { 588 // default value for unprocessed characters 589 pWidthArray[i-iFirstChar] = 0; 590 } 591 592 dprintf2(("Char 0x%x('%c') -> width %d", i, i<256? i: '.', pWidthArray[i-iFirstChar])); 593 } 594 595 return ret; 596 } 597 //****************************************************************************** 598 //****************************************************************************** 599 BOOL WIN32API GetCharWidth32W(HDC hdc, UINT iFirstChar, UINT iLastChar, PINT pWidthArray) 600 { 601 BOOL ret = FALSE; 602 603 for (int i = iFirstChar; i <= iLastChar; i++) 604 { 605 SIZE size; 606 WCHAR wc = i; 607 608 if (GetTextExtentPointW(hdc, &wc, 1, &size)) 609 { 610 pWidthArray[i-iFirstChar] = size.cx; 611 // at least one character was processed 612 ret = TRUE; 613 } 614 else 615 { 616 // default value for unprocessed characters 617 pWidthArray[i-iFirstChar] = 0; 618 } 619 620 dprintf2(("Char 0x%x('%c') -> width %d", i, i<256? i: '.', pWidthArray[i-iFirstChar])); 621 } 622 623 return ret; 624 } 625 //****************************************************************************** 626 // GetStringWidthW 627 // 628 // Return the width of each character in the string 629 // 630 // Parameters: 631 // HDC hdc - device context handle 632 // LPWSTR lpszString - unicod string pointer 633 // UINT cbString - number of valid characters in string 634 // PINT pWidthArray - array that receives the character width (must be 635 // large enough to contain cbString elements 636 // 637 // Returns: 638 // FALSE - failure 639 // TRUE - success 640 // 641 //****************************************************************************** 642 BOOL WIN32API GetStringWidthW(HDC hdc, LPWSTR lpszString, UINT cbString, PINT pWidthArray) 643 { 644 return FT2Module.Ft2GetStringWidthW(hdc, lpszString, cbString, pWidthArray); 645 } 646 //****************************************************************************** 647 //****************************************************************************** 648 BOOL WIN32API GetCharWidthFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar, PFLOAT pxBUffer) 649 { 650 dprintf(("ERROR: GDI32: GetCharWidthFloatA, not implemented\n")); 651 DebugInt3(); 652 return(FALSE); 653 } 654 //****************************************************************************** 655 //****************************************************************************** 656 BOOL WIN32API GetCharWidthFloatW(HDC hdc, UINT iFirstChar, UINT iLastChar, PFLOAT pxBUffer) 657 { 658 dprintf(("ERROR: GDI32: GetCharWidthFloatW, not implemented\n")); 659 DebugInt3(); 660 return(FALSE); 661 } 662 //****************************************************************************** 663 //****************************************************************************** 664 BOOL WIN32API GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar, LPABC abc) 665 { 666 if(FT2Module.isEnabled() == FALSE) 667 {//fallback method 668 return O32_GetCharABCWidths(hdc, firstChar, lastChar, abc); 669 } 670 671 INT i, wlen, count = (INT)(lastChar - firstChar + 1); 672 LPSTR str; 673 LPWSTR wstr; 674 BOOL ret = TRUE; 675 676 if(count <= 0) { 677 dprintf(("ERROR: Invalid parameter!!")); 678 SetLastError(ERROR_INVALID_PARAMETER); 679 return FALSE; 680 } 681 682 str = (LPSTR)HeapAlloc(GetProcessHeap(), 0, count); 683 for(i = 0; i < count; i++) 684 str[i] = (BYTE)(firstChar + i); 685 686 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL); 687 688 for(i = 0; i < wlen; i++) 689 { 690 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc)) 691 { 692 ret = FALSE; 693 break; 694 } 695 abc++; 696 } 697 698 HeapFree(GetProcessHeap(), 0, str); 699 HeapFree(GetProcessHeap(), 0, wstr); 700 701 return ret; 702 } 703 //****************************************************************************** 704 //****************************************************************************** 705 BOOL WIN32API GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar, LPABC abc) 706 { 707 if(FT2Module.isEnabled() == FALSE) 708 {//no fallback method (yet) 709 DebugInt3(); 710 return FALSE; 711 } 712 713 int i; 714 GLYPHMETRICS gm; 715 716 for (i=firstChar;i<=lastChar;i++) 717 { 718 if(GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL) == GDI_ERROR) 719 { 720 dprintf(("ERROR: GetGlyphOutlineW failed!!")); 721 return FALSE; 722 } 723 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x; 724 abc[i-firstChar].abcB = gm.gmBlackBoxX; 725 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX; 726 dprintf2(("GetCharABCWidthsW %d (%d,%d,%d)", i, abc[i-firstChar].abcA, abc[i-firstChar].abcB, abc[i-firstChar].abcC)); 727 } 728 return TRUE; 729 } 730 //****************************************************************************** 731 //****************************************************************************** 732 BOOL WIN32API GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar, LPABCFLOAT pxBUffer) 733 { 734 dprintf(("ERROR: GDI32: GetCharABCWidthsFloatA, not implemented\n")); 735 DebugInt3(); 736 return(FALSE); 737 } 738 //****************************************************************************** 739 //****************************************************************************** 740 BOOL WIN32API GetCharABCWidthsFloatW(HDC hdc, 741 UINT iFirstChar, 742 UINT iLastChar, 743 LPABCFLOAT pxBUffer) 744 { 745 dprintf(("ERROR: GDI32: GetCharABCWidthsFloatA, not implemented\n")); 746 DebugInt3(); 747 return(FALSE); 748 } 749 //****************************************************************************** 750 //******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.