Index: trunk/src/gdi32/ft2supp.cpp
===================================================================
--- trunk/src/gdi32/ft2supp.cpp	(revision 10390)
+++ trunk/src/gdi32/ft2supp.cpp	(revision 10391)
@@ -109,7 +109,4 @@
        pfnFt2QueryStringWidthW = (PFN_FT2QUERYSTRINGWIDTHW)QueryProcAddress("Ft2QueryStringWidthW");
        if(!pfnFt2QueryStringWidthW) dprintf(("Ft2QueryStringWidthW not found!!"));
-
-       pfnFt2GetCharacterPlacementW = (PFN_FT2GETCHARACTERPLACEMENTW)QueryProcAddress("Ft2GetCharacterPlacementW");
-       if(!pfnFt2GetCharacterPlacementW) dprintf(("pfnFt2GetCharacterPlacementW not found!!"));
 
        // Do not register functions for Mozilla plugins
Index: trunk/src/gdi32/ft2supp.h
===================================================================
--- trunk/src/gdi32/ft2supp.h	(revision 10390)
+++ trunk/src/gdi32/ft2supp.h	(revision 10391)
@@ -94,5 +94,5 @@
    DWORD Ft2GetGlyphOutline(HPS hps, UINT glyph, UINT format, LPGLYPHMETRICS lpgm, DWORD buflen, LPVOID buf, const MAT2* lpmat); 
 
-   BOOL  Ft2GetTextExtentW(HPS hps, LONG lCount1,LPCWSTR pchString,LONG lCount2,PPOINTLOS2 aptlPoints);
+   BOOL  Ft2GetTextExtentW(HPS hps, LONG lCount1,LPCWSTR pchString, PPOINTLOS2 pwidthHeight);
    BOOL  Ft2CharStringPosAtA(HPS hps,PPOINTLOS2 ptl,PRECTLOS2 rct,ULONG flOptions,LONG lCount,LPCSTR pchString,CONST INT *alAdx, ULONG fuWin32Options);
    BOOL  Ft2CharStringPosAtW(HPS hps,PPOINTLOS2 ptl,PRECTLOS2 rct,ULONG flOptions,LONG lCount,LPCWSTR pchString,CONST INT *alAdx, ULONG fuWin32Options);
Index: trunk/src/gdi32/text.cpp
===================================================================
--- trunk/src/gdi32/text.cpp	(revision 10390)
+++ trunk/src/gdi32/text.cpp	(revision 10391)
@@ -1,3 +1,3 @@
-/* $Id: text.cpp,v 1.40 2004-01-11 11:42:22 sandervl Exp $ */
+/* $Id: text.cpp,v 1.41 2004-01-14 11:07:35 sandervl Exp $ */
 
 /*
@@ -27,4 +27,5 @@
 #include "ft2supp.h"
 #include "font.h"
+#include <math.h>
 
 #define DBG_LOCALLOG    DBG_text
@@ -34,4 +35,19 @@
 #define ELLIPSISLEN 3
 
+//******************************************************************************
+//******************************************************************************
+CHAR getBrokenDBCS( LPCSTR strA, INT lenA )
+{
+    int i;
+
+    for( i = 0; i < lenA; i++ )
+        if( IsDBCSLeadByte( strA[ i ]))
+            i++;
+
+    if( lenA < i ) // terminated at DBCS lead byte
+        return strA[ lenA ];
+
+    return 0;
+}
 //******************************************************************************
 //******************************************************************************
@@ -91,4 +107,5 @@
   POINTLOS2 ptl;
   LONG hits;
+  RECT rect;
 
   if (!pHps || (cbCount < 0) || (((lpszStringA == NULL && !fUnicode) || (lpszStringW == NULL && fUnicode)) && (cbCount != 0)))
@@ -100,5 +117,5 @@
 
   if(cbCount == -1) {
-       if(fUnicode) 
+       if(fUnicode)
             cbCount = lstrlenW(lpszStringW);
        else cbCount = lstrlenA(lpszStringA);
@@ -128,4 +145,27 @@
   Y = oldyinv - Y;
 #endif
+
+  // When using font association, the height of DBCS and SBCS chars may be different.
+  // In this case, background color make stair below chars
+  if( IsDBCSEnv() && !lprc && ( GetBkMode( hdc ) & OPAQUE ))
+  {
+      SIZE   size;
+      TEXTMETRICA tmA;
+
+      if( fUnicode )
+        GetTextExtentPointW( hdc, lpszStringW, cbCount, &size );
+      else
+        GetTextExtentPointA( hdc, lpszStringA, cbCount, &size );
+
+      GetTextMetricsA( hdc, &tmA );
+
+      rect.left = X;
+      rect.right = X + size.cx;
+      rect.top = Y;
+      rect.bottom = Y + tmA.tmHeight;
+
+      lprc = &rect;
+      fuOptions |= ETO_OPAQUE;
+  }
 
   //CB: add metafile info
@@ -264,5 +304,5 @@
 #endif
 
-  if(fUnicode) 
+  if(fUnicode)
        hits = FT2Module.Ft2CharStringPosAtW(pHps->hps,&ptl,&pmRect,flOptions,cbCount,lpszStringW,lpDx, fuOptions & ETO_GLYPH_INDEX);
   else hits = FT2Module.Ft2CharStringPosAtA(pHps->hps,&ptl,&pmRect,flOptions,cbCount,lpszStringA,lpDx, fuOptions & ETO_GLYPH_INDEX);
@@ -383,7 +423,28 @@
    BOOL ret = FALSE;
    INT  wlen;
-   LPWSTR p = FONT_mbtowc(hdc, lpsz, cbString, &wlen, NULL);
+   LPWSTR p;
+   CHAR brokenDBCS = 0;
+
+   if( IsDBCSEnv())
+      brokenDBCS = getBrokenDBCS( lpsz, cbString );
+
+   if( brokenDBCS )
+      cbString--;
+
+   p = FONT_mbtowc(hdc, lpsz, cbString, &wlen, NULL);
    if (p) {
        ret = GetTextExtentPointW( hdc, p, wlen, lpsSize );
+       // For broken DBCS. Correct for FIXED WIDTH, but approx. for VARIABLE WIDTH
+       if( brokenDBCS )
+       {
+          TEXTMETRICA tmA;
+
+          GetTextMetricsA( hdc, &tmA );
+          lpsSize->cx += tmA.tmAveCharWidth;
+
+          if( cbString == 0 )
+            lpsSize->cy = tmA.tmHeight;
+       }
+
        HeapFree( GetProcessHeap(), 0, p );
    }
@@ -399,5 +460,4 @@
 {
    BOOL       rc;
-   POINTLOS2  pts[TXTBOXOS_COUNT];
    POINTLOS2  widthHeight = { 0, 0};
    pDCData    pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
@@ -436,6 +496,4 @@
 
       dprintf(("WARNING: string longer than 512 chars; splitting up"));
-      lpSize->cx = 0;
-      lpSize->cy = 0;
       while(cbString) {
          cbStringNew = min(500, cbString);
@@ -452,5 +510,5 @@
    }
 
-   rc = FT2Module.Ft2GetTextExtentW(pHps->hps, cbString, lpString, TXTBOXOS_COUNT, pts);
+   rc = FT2Module.Ft2GetTextExtentW(pHps->hps, cbString, lpString, &widthHeight);
    if(rc == FALSE)
    {
@@ -458,5 +516,4 @@
       return FALSE;
    }
-   calcDimensions(pts, &widthHeight);
    lpSize->cx = widthHeight.x;
    lpSize->cy = widthHeight.y;
@@ -498,29 +555,70 @@
     BOOL ret;
     INT wlen;
-    LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
-    ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
-    if (lpnFit) *lpnFit = WideCharToMultiByte(CP_ACP,0,p,*lpnFit,NULL,0,NULL,NULL);
-    if( IsDBCSEnv() && alpDx ) /* index of alpDx between ansi and wide may not match in DBCS !!! */
-    {
-        LPINT alpDxNew = ( LPINT )HeapAlloc( GetProcessHeap(), 0, sizeof( alpDx[ 0 ] ) * *lpnFit );
+    LPWSTR p;
+    INT nFit;
+    TEXTMETRICA tmA;
+    CHAR brokenDBCS = 0;
+
+    if( IsDBCSEnv())
+    {
+        brokenDBCS = getBrokenDBCS( str, count );
+
+        GetTextMetricsA( hdc, &tmA );
+    }
+
+    if( brokenDBCS )
+       count--;
+
+    p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
+    ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, &nFit, alpDx, size);
+    nFit = WideCharToMultiByte(CP_ACP,0,p,nFit,NULL,0,NULL,NULL);
+    if( IsDBCSEnv() && alpDx ) // index of alpDx between ansi and wide may not match in DBCS !!!
+    {
+        LPINT alpDxNew = ( LPINT )HeapAlloc( GetProcessHeap(), 0, sizeof( alpDx[ 0 ] ) * ( nFit + 1 ));
+        INT prevDx;
         int i, j;
 
-        for( i = j = 0; i < *lpnFit; i++, j++ )
+        for( i = j = 0; i < nFit; i++, j++ )
         {
             if( IsDBCSLeadByte( str[ i ]))
             {
-                alpDxNew[ i++ ] = alpDx[ j ] >> 1;
-                if( i < *lpnFit )
-                    alpDxNew[ i ] = alpDx[ j ] >> 1;
+                prevDx = ( i > 0 ) ? alpDxNew[ i - 1 ] : 0;
+                alpDxNew[ i++ ] = prevDx + tmA.tmAveCharWidth;
+                if( i >= nFit )
+                    break;
             }
-            else
-                alpDxNew[ i ] = alpDx[ j ];
-
+            alpDxNew[ i ] = alpDx[ j ];
         }
 
-        memcpy( alpDx, alpDxNew, sizeof( alpDx[ 0 ] ) * *lpnFit );
+        if(( nFit < count ) && IsDBCSLeadByte( str[ nFit ]))
+        {
+            prevDx = ( nFit > 0 ) ? alpDxNew[ nFit - 1 ] : 0;
+            if( maxExt >= prevDx + tmA.tmAveCharWidth )
+                alpDxNew[ nFit++ ] = prevDx + tmA.tmAveCharWidth;
+        }
+
+        memcpy( alpDx, alpDxNew, sizeof( alpDx[ 0 ] ) * nFit );
 
         HeapFree( GetProcessHeap(), 0, alpDxNew );
     }
+
+    // for broken DBCS. correct for FIXED WIDTH, not approx. for VARIABLE WIDTH
+    if( brokenDBCS )
+    {
+       size->cx += tmA.tmAveCharWidth;
+       if( count == 0 )
+          size->cy = tmA.tmHeight;
+
+       if(( maxExt > size->cx ) && ( nFit <= count )) // decreaed count by 1 above
+       {
+          if( alpDx )
+            alpDx[ nFit ] = size->cx;
+
+          nFit++;
+       }
+    }
+
+    if (lpnFit) *lpnFit = nFit;
+
     HeapFree( GetProcessHeap(), 0, p );
     return ret;
@@ -536,27 +634,29 @@
                                     LPSIZE  size)
 {
-    int index, nFit, extent;
+    int i, nFit, extent;
     SIZE tSize;
     BOOL ret = FALSE;
 
     size->cx = size->cy = nFit = extent = 0;
-    for(index = 0; index < count; index++)
-    {
- 	if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
-        /* GetTextExtentPoint includes intercharacter spacing. */
-        /* FIXME - justification needs doing yet.  Remember that the base
-         * data will not be in logical coordinates.
-         */
-	extent += tSize.cx;
-	if( !lpnFit || extent <= maxExt )
-        /* It is allowed to be equal. */
-        {
-	    nFit++;
-	    if( alpDx ) alpDx[index] = extent;
-        }
-	if( tSize.cy > size->cy ) size->cy = tSize.cy;
-	str++;
-    }
-    size->cx = extent;
+
+    for( i = 1; i <= count; i++ )
+    {
+        if( !GetTextExtentPoint32W( hdc, str, i, &tSize )) goto done;
+
+        if( maxExt < tSize.cx )
+            break;
+
+        if( alpDx )
+            alpDx[ nFit ] = tSize.cx;
+
+        nFit++;
+    }
+
+    if( i >= count )
+        size->cx = tSize.cx;
+    else if( !GetTextExtentPoint32W( hdc, str, count, size )) goto done;
+
+    size->cy = tSize.cy; // The height of a font is constant.
+
     if(lpnFit) *lpnFit = nFit;
     ret = TRUE;
@@ -572,10 +672,10 @@
 {
     BOOL ret = FALSE;
-      
+
     for (int i = iFirstChar; i <= iLastChar; i++)
     {
         SIZE size;
         CHAR c = i;
-        
+
         if (GetTextExtentPointA(hdc, &c, 1, &size))
         {
@@ -589,8 +689,8 @@
             pWidthArray[i-iFirstChar] = 0;
         }
-        
+
         dprintf2(("Char 0x%x('%c') -> width %d", i, i<256? i: '.', pWidthArray[i-iFirstChar]));
     }
-   
+
     return ret;
 }
@@ -600,10 +700,10 @@
 {
     BOOL ret = FALSE;
-      
+
     for (int i = iFirstChar; i <= iLastChar; i++)
     {
         SIZE size;
         WCHAR wc = i;
-        
+
         if (GetTextExtentPointW(hdc, &wc, 1, &size))
         {
@@ -617,8 +717,8 @@
             pWidthArray[i-iFirstChar] = 0;
         }
-        
+
         dprintf2(("Char 0x%x('%c') -> width %d", i, i<256? i: '.', pWidthArray[i-iFirstChar]));
     }
-   
+
     return ret;
 }
@@ -632,7 +732,7 @@
 //    LPWSTR lpszString     - unicod string pointer
 //    UINT   cbString       - number of valid characters in string
-//    PINT   pWidthArray    - array that receives the character width (must be 
+//    PINT   pWidthArray    - array that receives the character width (must be
 //                            large enough to contain cbString elements
-//   
+//
 // Returns:
 //    FALSE                 - failure
@@ -664,5 +764,5 @@
 BOOL WIN32API GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar, LPABC abc)
 {
-    if(FT2Module.isEnabled() == FALSE) 
+    if(FT2Module.isEnabled() == FALSE)
     {//fallback method
         return O32_GetCharABCWidths(hdc, firstChar, lastChar, abc);
@@ -682,5 +782,5 @@
     str = (LPSTR)HeapAlloc(GetProcessHeap(), 0, count);
     for(i = 0; i < count; i++)
-	str[i] = (BYTE)(firstChar + i);
+    str[i] = (BYTE)(firstChar + i);
 
     wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
@@ -688,10 +788,10 @@
     for(i = 0; i < wlen; i++)
     {
-	if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
-	{
-	    ret = FALSE;
-	    break;
-	}
-	abc++;
+    if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
+    {
+        ret = FALSE;
+        break;
+    }
+    abc++;
     }
 
@@ -705,5 +805,5 @@
 BOOL WIN32API GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar, LPABC abc)
 {
-    if(FT2Module.isEnabled() == FALSE) 
+    if(FT2Module.isEnabled() == FALSE)
     {//no fallback method (yet)
         DebugInt3();
@@ -714,7 +814,7 @@
     GLYPHMETRICS gm;
 
-    for (i=firstChar;i<=lastChar;i++) 
-    {
-        if(GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL) == GDI_ERROR) 
+    for (i=firstChar;i<=lastChar;i++)
+    {
+        if(GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL) == GDI_ERROR)
         {
             dprintf(("ERROR: GetGlyphOutlineW failed!!"));
@@ -749,2 +849,3 @@
 //******************************************************************************
 //******************************************************************************
+
