Ignore:
Timestamp:
Jan 11, 2004, 12:43:22 PM (22 years ago)
Author:
sandervl
Message:

Update

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:15 sandervl Exp $ */
     1/* $Id: text.cpp,v 1.40 2004-01-11 11:42:22 sandervl Exp $ */
    22
    33/*
    44 * GDI32 text apis
    55 *
    6  * Based on Wine code (991031) (objects\text.c)
     6 * Based on Wine/ReWind code (objects\text.c, objects\font.c)
    77 *
    88 * Copyright 1993, 1994 Alexandre Julliard
     9 *           1997 Alex Korobka
     10 *
    911 * Copyright 1999-2000 Christoph Bratschi
     12 * Copyright 2002-2003 Innotek Systemberatung GmbH (sandervl@innotek.de)
    1013 *
    1114 * Project Odin Software License can be found in LICENSE.TXT
     
    2124#include <dcdata.h>
    2225#include <unicode.h>
     26#include "dibsect.h"
     27#include "ft2supp.h"
    2328#include "font.h"
    2429
     
    7782//#define INVERT_SETYINVERSION
    7883//******************************************************************************
    79 BOOL InternalTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut)
     84BOOL 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)
    8087{
    8188  pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
     
    8592  LONG hits;
    8693
    87   if (!pHps || (cbCount < 0) || ((lpszString == NULL) && (cbCount != 0)))
     94  if (!pHps || (cbCount < 0) || (((lpszStringA == NULL && !fUnicode) || (lpszStringW == NULL && fUnicode)) && (cbCount != 0)))
    8895  {
    8996        dprintf(("InternalTextOutA: invalid parameter"));
     
    9299  }
    93100
     101  if(cbCount == -1) {
     102       if(fUnicode)
     103            cbCount = lstrlenW(lpszStringW);
     104       else cbCount = lstrlenA(lpszStringA);
     105  }
     106
    94107  if (cbCount > 512)
    95108  {
     
    98111        return FALSE;
    99112  }
    100   if (fuOptions & ~((UINT)(ETO_CLIPPED | ETO_OPAQUE)))
     113  if (fuOptions & ~((UINT)(ETO_CLIPPED | ETO_OPAQUE | ETO_GLYPH_INDEX)))
    101114  {
    102115        dprintf(("InternalTextOutA: invalid fuOptions"));
     
    150163  else
    151164  {
    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);
    156169        return FALSE;
    157170    }
     171  }
     172
     173  if((lpszStringA || lpszStringW) && cbCount) {
     174      DIBSECTION_CHECK_IF_DIRTY(hdc);
    158175  }
    159176
     
    176193        SelectObject(hdc, oldbrush);
    177194        DeleteObject(hbrush);
     195
     196        DIBSECTION_MARK_INVALID(hdc);
     197
    178198        return TRUE;
    179199#endif
     
    244264#endif
    245265
    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);
    247269
    248270  if (lprc && ((align & 0x18) == TA_BASELINE))
    249     OSLibGpiSetTextAlignment(pHps,pmHAlign,pmVAlign);
     271      OSLibGpiSetTextAlignment(pHps,pmHAlign,pmVAlign);
    250272
    251273  if(hits == GPIOS_ERROR) {
    252         dprintf(("InternalTextOutA: OSLibGpiCharStringPosAt returned GPIOS_ERROR"));
     274      dprintf(("InternalTextOutA: OSLibGpiCharStringPosAt returned GPIOS_ERROR"));
    253275#ifdef INVERT_SETYINVERSION
    254         GpiEnableYInversion(pHps->hps, oldyinv);
    255 #endif
    256         return FALSE;
     276      GpiEnableYInversion(pHps->hps, oldyinv);
     277#endif
     278      return FALSE;
    257279  }
    258280
    259281  if (getAlignUpdateCP(pHps))
    260282  {
    261     OSLibGpiQueryCurrentPosition(pHps,&ptl);
    262     ptl.y -= getWorldYDeltaFor1Pixel(pHps);
     283      OSLibGpiQueryCurrentPosition(pHps,&ptl);
     284      ptl.y -= getWorldYDeltaFor1Pixel(pHps);
    263285#ifndef INVERT
    264     ptl.y += vertAdjust;
    265 #endif
    266     OSLibGpiSetCurrentPosition(pHps,&ptl);
     286      ptl.y += vertAdjust;
     287#endif
     288      OSLibGpiSetCurrentPosition(pHps,&ptl);
    267289  }
    268290
     
    270292  GpiEnableYInversion(pHps->hps, oldyinv);
    271293#endif
     294
     295  DIBSECTION_MARK_INVALID(hdc);
     296
    272297  return TRUE;
    273298}
    274299//******************************************************************************
    275300//******************************************************************************
    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;
     301BOOL WIN32API ExtTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,UINT cbCount,CONST INT *lpDx)
     302{
    279303  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);
    296314
    297315  return(rc);
     
    299317//******************************************************************************
    300318//******************************************************************************
    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 //******************************************************************************
    330319BOOL WIN32API ExtTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCWSTR lpszString,UINT cbCount,CONST int *lpDx)
    331320{
    332321  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);
    337327}
    338328//******************************************************************************
     
    341331{
    342332   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);
    344334}
    345335//******************************************************************************
     
    348338{
    349339   dprintf(("GDI32: TextOutW %x (%d,%d) %d %.*ls", hdc, nXStart, nYStart, cbString, cbString, lpszString));
    350    return InternalTextOutW(hdc,nXStart,nYStart,0,NULL,lpszString,cbString,NULL,FALSE);
     340   return InternalTextOutAW(hdc,nXStart,nYStart,0,NULL, NULL, lpszString,cbString,NULL,FALSE, TRUE);
    351341}
    352342//******************************************************************************
     
    358348  for (INT x = 0;x < cStrings;x++)
    359349  {
    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;
    364354  }
    365355
     
    374364  for (INT x = 0;x < cStrings;x++)
    375365  {
    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;
    380370  }
    381371
     
    383373}
    384374//******************************************************************************
     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//
    385379//******************************************************************************
    386380BOOL WIN32API GetTextExtentPointA(HDC hdc, LPCTSTR lpsz, int cbString,
     
    428422   if(cbString == 0)
    429423   {
     424      dprintf(("!WARNING!: GDI32: GetTextExtentPointW invalid parameter!"));
    430425      SetLastError(ERROR_SUCCESS);
    431426      return TRUE;
    432427   }
     428
     429   if(pHps->isPrinter)
     430       ReallySetCharAttrs(pHps);
     431
    433432   if(cbString > 512)
    434433   {
     
    447446         lpSize->cx += newSize.cx;
    448447         lpSize->cy  = max(newSize.cy, lpSize->cy);
    449          lpString     += cbStringNew;
     448         lpString    += cbStringNew;
    450449         cbString -= cbStringNew;
    451450      }
     
    453452   }
    454453
    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);
    465455   if(rc == FALSE)
    466456   {
     
    476466       LONG alArray[2];
    477467
    478        if (OSLibDevQueryCaps(pHps, OSLIB_CAPS_HORIZONTAL_RESOLUTION, 2, &alArray[0]))
    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];
    480470   }
    481471
     
    553543    for(index = 0; index < count; index++)
    554544    {
    555     if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
     545        if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
    556546        /* GetTextExtentPoint includes intercharacter spacing. */
    557547        /* FIXME - justification needs doing yet.  Remember that the base
    558548         * data will not be in logical coordinates.
    559549         */
    560     extent += tSize.cx;
    561     if( !lpnFit || extent <= maxExt )
     550        extent += tSize.cx;
     551        if( !lpnFit || extent <= maxExt )
    562552        /* It is allowed to be equal. */
    563553        {
    564         nFit++;
    565         if( alpDx ) alpDx[index] = extent;
     554            nFit++;
     555            if( alpDx ) alpDx[index] = extent;
    566556        }
    567     if( tSize.cy > size->cy ) size->cy = tSize.cy;
    568     str++;
     557        if( tSize.cy > size->cy ) size->cy = tSize.cy;
     558        str++;
    569559    }
    570560    size->cx = extent;
     
    579569//******************************************************************************
    580570//******************************************************************************
     571BOOL 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//******************************************************************************
     599BOOL 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//******************************************************************************
     642BOOL WIN32API GetStringWidthW(HDC hdc, LPWSTR lpszString, UINT cbString, PINT pWidthArray)
     643{
     644    return FT2Module.Ft2GetStringWidthW(hdc, lpszString, cbString, pWidthArray);
     645}
     646//******************************************************************************
     647//******************************************************************************
     648BOOL 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//******************************************************************************
     656BOOL 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//******************************************************************************
     664BOOL 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//******************************************************************************
     705BOOL 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//******************************************************************************
     732BOOL 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//******************************************************************************
     740BOOL 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.