Changeset 20927


Ignore:
Timestamp:
Jan 14, 2004, 12:08:08 PM (21 years ago)
Author:
sandervl
Message:

KOM: Misc DBCS related text fixes

Location:
tags/trunk/src/gdi32
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified tags/trunk/src/gdi32/ft2supp.cpp

    r20926 r20927  
    109109       pfnFt2QueryStringWidthW = (PFN_FT2QUERYSTRINGWIDTHW)QueryProcAddress("Ft2QueryStringWidthW");
    110110       if(!pfnFt2QueryStringWidthW) dprintf(("Ft2QueryStringWidthW not found!!"));
    111 
    112        pfnFt2GetCharacterPlacementW = (PFN_FT2GETCHARACTERPLACEMENTW)QueryProcAddress("Ft2GetCharacterPlacementW");
    113        if(!pfnFt2GetCharacterPlacementW) dprintf(("pfnFt2GetCharacterPlacementW not found!!"));
    114111
    115112       // Do not register functions for Mozilla plugins
  • TabularUnified tags/trunk/src/gdi32/ft2supp.h

    r20910 r20927  
    9494   DWORD Ft2GetGlyphOutline(HPS hps, UINT glyph, UINT format, LPGLYPHMETRICS lpgm, DWORD buflen, LPVOID buf, const MAT2* lpmat);
    9595
    96    BOOL  Ft2GetTextExtentW(HPS hps, LONG lCount1,LPCWSTR pchString,LONG lCount2,PPOINTLOS2 aptlPoints);
     96   BOOL  Ft2GetTextExtentW(HPS hps, LONG lCount1,LPCWSTR pchString, PPOINTLOS2 pwidthHeight);
    9797   BOOL  Ft2CharStringPosAtA(HPS hps,PPOINTLOS2 ptl,PRECTLOS2 rct,ULONG flOptions,LONG lCount,LPCSTR pchString,CONST INT *alAdx, ULONG fuWin32Options);
    9898   BOOL  Ft2CharStringPosAtW(HPS hps,PPOINTLOS2 ptl,PRECTLOS2 rct,ULONG flOptions,LONG lCount,LPCWSTR pchString,CONST INT *alAdx, ULONG fuWin32Options);
  • TabularUnified tags/trunk/src/gdi32/text.cpp

    r20910 r20927  
    1 /* $Id: text.cpp,v 1.40 2004-01-11 11:42:22 sandervl Exp $ */
     1/* $Id: text.cpp,v 1.41 2004-01-14 11:07:35 sandervl Exp $ */
    22
    33/*
     
    2727#include "ft2supp.h"
    2828#include "font.h"
     29#include <math.h>
    2930
    3031#define DBG_LOCALLOG    DBG_text
     
    3435#define ELLIPSISLEN 3
    3536
     37//******************************************************************************
     38//******************************************************************************
     39CHAR getBrokenDBCS( LPCSTR strA, INT lenA )
     40{
     41    int i;
     42
     43    for( i = 0; i < lenA; i++ )
     44        if( IsDBCSLeadByte( strA[ i ]))
     45            i++;
     46
     47    if( lenA < i ) // terminated at DBCS lead byte
     48        return strA[ lenA ];
     49
     50    return 0;
     51}
    3652//******************************************************************************
    3753//******************************************************************************
     
    91107  POINTLOS2 ptl;
    92108  LONG hits;
     109  RECT rect;
    93110
    94111  if (!pHps || (cbCount < 0) || (((lpszStringA == NULL && !fUnicode) || (lpszStringW == NULL && fUnicode)) && (cbCount != 0)))
     
    100117
    101118  if(cbCount == -1) {
    102        if(fUnicode) 
     119       if(fUnicode)
    103120            cbCount = lstrlenW(lpszStringW);
    104121       else cbCount = lstrlenA(lpszStringA);
     
    128145  Y = oldyinv - Y;
    129146#endif
     147
     148  // When using font association, the height of DBCS and SBCS chars may be different.
     149  // In this case, background color make stair below chars
     150  if( IsDBCSEnv() && !lprc && ( GetBkMode( hdc ) & OPAQUE ))
     151  {
     152      SIZE   size;
     153      TEXTMETRICA tmA;
     154
     155      if( fUnicode )
     156        GetTextExtentPointW( hdc, lpszStringW, cbCount, &size );
     157      else
     158        GetTextExtentPointA( hdc, lpszStringA, cbCount, &size );
     159
     160      GetTextMetricsA( hdc, &tmA );
     161
     162      rect.left = X;
     163      rect.right = X + size.cx;
     164      rect.top = Y;
     165      rect.bottom = Y + tmA.tmHeight;
     166
     167      lprc = &rect;
     168      fuOptions |= ETO_OPAQUE;
     169  }
    130170
    131171  //CB: add metafile info
     
    264304#endif
    265305
    266   if(fUnicode) 
     306  if(fUnicode)
    267307       hits = FT2Module.Ft2CharStringPosAtW(pHps->hps,&ptl,&pmRect,flOptions,cbCount,lpszStringW,lpDx, fuOptions & ETO_GLYPH_INDEX);
    268308  else hits = FT2Module.Ft2CharStringPosAtA(pHps->hps,&ptl,&pmRect,flOptions,cbCount,lpszStringA,lpDx, fuOptions & ETO_GLYPH_INDEX);
     
    383423   BOOL ret = FALSE;
    384424   INT  wlen;
    385    LPWSTR p = FONT_mbtowc(hdc, lpsz, cbString, &wlen, NULL);
     425   LPWSTR p;
     426   CHAR brokenDBCS = 0;
     427
     428   if( IsDBCSEnv())
     429      brokenDBCS = getBrokenDBCS( lpsz, cbString );
     430
     431   if( brokenDBCS )
     432      cbString--;
     433
     434   p = FONT_mbtowc(hdc, lpsz, cbString, &wlen, NULL);
    386435   if (p) {
    387436       ret = GetTextExtentPointW( hdc, p, wlen, lpsSize );
     437       // For broken DBCS. Correct for FIXED WIDTH, but approx. for VARIABLE WIDTH
     438       if( brokenDBCS )
     439       {
     440          TEXTMETRICA tmA;
     441
     442          GetTextMetricsA( hdc, &tmA );
     443          lpsSize->cx += tmA.tmAveCharWidth;
     444
     445          if( cbString == 0 )
     446            lpsSize->cy = tmA.tmHeight;
     447       }
     448
    388449       HeapFree( GetProcessHeap(), 0, p );
    389450   }
     
    399460{
    400461   BOOL       rc;
    401    POINTLOS2  pts[TXTBOXOS_COUNT];
    402462   POINTLOS2  widthHeight = { 0, 0};
    403463   pDCData    pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
     
    436496
    437497      dprintf(("WARNING: string longer than 512 chars; splitting up"));
    438       lpSize->cx = 0;
    439       lpSize->cy = 0;
    440498      while(cbString) {
    441499         cbStringNew = min(500, cbString);
     
    452510   }
    453511
    454    rc = FT2Module.Ft2GetTextExtentW(pHps->hps, cbString, lpString, TXTBOXOS_COUNT, pts);
     512   rc = FT2Module.Ft2GetTextExtentW(pHps->hps, cbString, lpString, &widthHeight);
    455513   if(rc == FALSE)
    456514   {
     
    458516      return FALSE;
    459517   }
    460    calcDimensions(pts, &widthHeight);
    461518   lpSize->cx = widthHeight.x;
    462519   lpSize->cy = widthHeight.y;
     
    498555    BOOL ret;
    499556    INT wlen;
    500     LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
    501     ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
    502     if (lpnFit) *lpnFit = WideCharToMultiByte(CP_ACP,0,p,*lpnFit,NULL,0,NULL,NULL);
    503     if( IsDBCSEnv() && alpDx ) /* index of alpDx between ansi and wide may not match in DBCS !!! */
    504     {
    505         LPINT alpDxNew = ( LPINT )HeapAlloc( GetProcessHeap(), 0, sizeof( alpDx[ 0 ] ) * *lpnFit );
     557    LPWSTR p;
     558    INT nFit;
     559    TEXTMETRICA tmA;
     560    CHAR brokenDBCS = 0;
     561
     562    if( IsDBCSEnv())
     563    {
     564        brokenDBCS = getBrokenDBCS( str, count );
     565
     566        GetTextMetricsA( hdc, &tmA );
     567    }
     568
     569    if( brokenDBCS )
     570       count--;
     571
     572    p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
     573    ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, &nFit, alpDx, size);
     574    nFit = WideCharToMultiByte(CP_ACP,0,p,nFit,NULL,0,NULL,NULL);
     575    if( IsDBCSEnv() && alpDx ) // index of alpDx between ansi and wide may not match in DBCS !!!
     576    {
     577        LPINT alpDxNew = ( LPINT )HeapAlloc( GetProcessHeap(), 0, sizeof( alpDx[ 0 ] ) * ( nFit + 1 ));
     578        INT prevDx;
    506579        int i, j;
    507580
    508         for( i = j = 0; i < *lpnFit; i++, j++ )
     581        for( i = j = 0; i < nFit; i++, j++ )
    509582        {
    510583            if( IsDBCSLeadByte( str[ i ]))
    511584            {
    512                 alpDxNew[ i++ ] = alpDx[ j ] >> 1;
    513                 if( i < *lpnFit )
    514                     alpDxNew[ i ] = alpDx[ j ] >> 1;
     585                prevDx = ( i > 0 ) ? alpDxNew[ i - 1 ] : 0;
     586                alpDxNew[ i++ ] = prevDx + tmA.tmAveCharWidth;
     587                if( i >= nFit )
     588                    break;
    515589            }
    516             else
    517                 alpDxNew[ i ] = alpDx[ j ];
    518 
     590            alpDxNew[ i ] = alpDx[ j ];
    519591        }
    520592
    521         memcpy( alpDx, alpDxNew, sizeof( alpDx[ 0 ] ) * *lpnFit );
     593        if(( nFit < count ) && IsDBCSLeadByte( str[ nFit ]))
     594        {
     595            prevDx = ( nFit > 0 ) ? alpDxNew[ nFit - 1 ] : 0;
     596            if( maxExt >= prevDx + tmA.tmAveCharWidth )
     597                alpDxNew[ nFit++ ] = prevDx + tmA.tmAveCharWidth;
     598        }
     599
     600        memcpy( alpDx, alpDxNew, sizeof( alpDx[ 0 ] ) * nFit );
    522601
    523602        HeapFree( GetProcessHeap(), 0, alpDxNew );
    524603    }
     604
     605    // for broken DBCS. correct for FIXED WIDTH, not approx. for VARIABLE WIDTH
     606    if( brokenDBCS )
     607    {
     608       size->cx += tmA.tmAveCharWidth;
     609       if( count == 0 )
     610          size->cy = tmA.tmHeight;
     611
     612       if(( maxExt > size->cx ) && ( nFit <= count )) // decreaed count by 1 above
     613       {
     614          if( alpDx )
     615            alpDx[ nFit ] = size->cx;
     616
     617          nFit++;
     618       }
     619    }
     620
     621    if (lpnFit) *lpnFit = nFit;
     622
    525623    HeapFree( GetProcessHeap(), 0, p );
    526624    return ret;
     
    536634                                    LPSIZE  size)
    537635{
    538     int index, nFit, extent;
     636    int i, nFit, extent;
    539637    SIZE tSize;
    540638    BOOL ret = FALSE;
    541639
    542640    size->cx = size->cy = nFit = extent = 0;
    543     for(index = 0; index < count; index++)
    544     {
    545         if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
    546         /* GetTextExtentPoint includes intercharacter spacing. */
    547         /* FIXME - justification needs doing yet.  Remember that the base
    548          * data will not be in logical coordinates.
    549          */
    550         extent += tSize.cx;
    551         if( !lpnFit || extent <= maxExt )
    552         /* It is allowed to be equal. */
    553         {
    554             nFit++;
    555             if( alpDx ) alpDx[index] = extent;
    556         }
    557         if( tSize.cy > size->cy ) size->cy = tSize.cy;
    558         str++;
    559     }
    560     size->cx = extent;
     641
     642    for( i = 1; i <= count; i++ )
     643    {
     644        if( !GetTextExtentPoint32W( hdc, str, i, &tSize )) goto done;
     645
     646        if( maxExt < tSize.cx )
     647            break;
     648
     649        if( alpDx )
     650            alpDx[ nFit ] = tSize.cx;
     651
     652        nFit++;
     653    }
     654
     655    if( i >= count )
     656        size->cx = tSize.cx;
     657    else if( !GetTextExtentPoint32W( hdc, str, count, size )) goto done;
     658
     659    size->cy = tSize.cy; // The height of a font is constant.
     660
    561661    if(lpnFit) *lpnFit = nFit;
    562662    ret = TRUE;
     
    572672{
    573673    BOOL ret = FALSE;
    574      
     674
    575675    for (int i = iFirstChar; i <= iLastChar; i++)
    576676    {
    577677        SIZE size;
    578678        CHAR c = i;
    579        
     679
    580680        if (GetTextExtentPointA(hdc, &c, 1, &size))
    581681        {
     
    589689            pWidthArray[i-iFirstChar] = 0;
    590690        }
    591        
     691
    592692        dprintf2(("Char 0x%x('%c') -> width %d", i, i<256? i: '.', pWidthArray[i-iFirstChar]));
    593693    }
    594    
     694
    595695    return ret;
    596696}
     
    600700{
    601701    BOOL ret = FALSE;
    602      
     702
    603703    for (int i = iFirstChar; i <= iLastChar; i++)
    604704    {
    605705        SIZE size;
    606706        WCHAR wc = i;
    607        
     707
    608708        if (GetTextExtentPointW(hdc, &wc, 1, &size))
    609709        {
     
    617717            pWidthArray[i-iFirstChar] = 0;
    618718        }
    619        
     719
    620720        dprintf2(("Char 0x%x('%c') -> width %d", i, i<256? i: '.', pWidthArray[i-iFirstChar]));
    621721    }
    622    
     722
    623723    return ret;
    624724}
     
    632732//    LPWSTR lpszString     - unicod string pointer
    633733//    UINT   cbString       - number of valid characters in string
    634 //    PINT   pWidthArray    - array that receives the character width (must be 
     734//    PINT   pWidthArray    - array that receives the character width (must be
    635735//                            large enough to contain cbString elements
    636 //   
     736//
    637737// Returns:
    638738//    FALSE                 - failure
     
    664764BOOL WIN32API GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar, LPABC abc)
    665765{
    666     if(FT2Module.isEnabled() == FALSE) 
     766    if(FT2Module.isEnabled() == FALSE)
    667767    {//fallback method
    668768        return O32_GetCharABCWidths(hdc, firstChar, lastChar, abc);
     
    682782    str = (LPSTR)HeapAlloc(GetProcessHeap(), 0, count);
    683783    for(i = 0; i < count; i++)
    684         str[i] = (BYTE)(firstChar + i);
     784    str[i] = (BYTE)(firstChar + i);
    685785
    686786    wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
     
    688788    for(i = 0; i < wlen; i++)
    689789    {
    690         if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
    691         {
    692             ret = FALSE;
    693             break;
    694         }
    695         abc++;
     790    if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
     791    {
     792        ret = FALSE;
     793        break;
     794    }
     795    abc++;
    696796    }
    697797
     
    705805BOOL WIN32API GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar, LPABC abc)
    706806{
    707     if(FT2Module.isEnabled() == FALSE) 
     807    if(FT2Module.isEnabled() == FALSE)
    708808    {//no fallback method (yet)
    709809        DebugInt3();
     
    714814    GLYPHMETRICS gm;
    715815
    716     for (i=firstChar;i<=lastChar;i++) 
    717     {
    718         if(GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL) == GDI_ERROR) 
     816    for (i=firstChar;i<=lastChar;i++)
     817    {
     818        if(GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL) == GDI_ERROR)
    719819        {
    720820            dprintf(("ERROR: GetGlyphOutlineW failed!!"));
     
    749849//******************************************************************************
    750850//******************************************************************************
     851
Note: See TracChangeset for help on using the changeset viewer.