Changeset 21628 for trunk/src


Ignore:
Timestamp:
Apr 21, 2011, 10:41:04 PM (14 years ago)
Author:
dmik
Message:

gdi32: Fixed broken TextOut API family that would draw text flipped along the base line.

Location:
trunk/src/gdi32
Files:
2 edited

Legend:

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

    r21304 r21628  
    199199DWORD CFT2Module::Ft2GetGlyphIndices(HPS hps, LPCWSTR str, int c, LPWORD pgi, DWORD fl)
    200200{
    201     DWORD  ret; 
     201    DWORD  ret;
    202202    USHORT sel;
    203203
    204     // All FreeType calls should be wrapped for saving FS 
     204    // All FreeType calls should be wrapped for saving FS
    205205    if(pfnGetGlyphIndices) {
    206206        sel  = RestoreOS2FS();
    207207        ret  = pfnGetGlyphIndices(hps, (WCHAR*)str, c, (ULONG*)pgi, fl);
    208208        SetFS(sel);
    209         return ret; 
     209        return ret;
    210210    }
    211211    //no fallback
     
    217217DWORD CFT2Module::Ft2GetGlyphOutline(HPS hps, UINT glyph, UINT format, LPGLYPHMETRICS lpgm, DWORD buflen, LPVOID buf, const MAT2* lpmat)
    218218{
    219     DWORD  ret; 
     219    DWORD  ret;
    220220    USHORT sel;
    221221
    222     // All FreeType calls should be wrapped for saving FS 
     222    // All FreeType calls should be wrapped for saving FS
    223223    if (pfnFt2GetGlyphOutline)
    224224    {
     
    226226        ret  = pfnFt2GetGlyphOutline (hps, glyph, format, lpgm, buflen, buf, lpmat);
    227227        SetFS(sel);
    228         return ret; 
    229     }
    230    
     228        return ret;
     229    }
     230
    231231    //no fallback
    232232    SetLastError(ERROR_INVALID_FUNCTION_W);
     
    313313//******************************************************************************
    314314//******************************************************************************
     315struct CTISTATE
     316{
     317    pDCData pHps;
     318    BOOL restoreInversion;
     319    BOOL restoreMatrix;
     320    LONG oldYInversion;
     321    MATRIXLF mlf;
     322};
     323
     324static void CompensateTextInversion(pDCData pHps, PPOINTLOS2 ptl, PRECTLOS2 rct,
     325                                    CTISTATE *state)
     326{
     327    state->pHps = pHps;
     328    state->restoreInversion = FALSE;
     329    state->restoreMatrix = FALSE;
     330
     331    // The target HPS is most likely set up for Y inversion, to bring the origin
     332    // from the bottom-left corner (PM) to the top-left (Win). However, PM text
     333    // drawing routines make an exception for themselves and produce correct
     334    // top-left oriented glyphs despite the bottom-left oriented coordinate
     335    // space. Having the mentioned Y inversion makes them flip and display
     336    // glyphs top to bottom. We need to cancel this flip to get the correct
     337    // text orientation.
     338
     339    GpiQueryDefaultViewMatrix(pHps->hps, 9, &state->mlf);
     340
     341    if (state->mlf.fxM11 == MAKEFIXED(1, 0) && state->mlf.fxM12 == 0 &&
     342        state->mlf.lM13 == 0 &&
     343        state->mlf.fxM21 == 0 && state->mlf.fxM22 == MAKEFIXED(1, 0) &&
     344        state->mlf.lM23 == 0 &&
     345        state->mlf.lM31 == 0 && state->mlf.lM32 == 0 && state->mlf.lM33 == 1)
     346    {
     347        // the most common case: the identity matrix, the inversion is done...
     348#ifdef INVERT
     349        // ...through the special GPI call, cancel it and correct ptl/rct
     350        state->oldYInversion = GpiQueryYInversion(pHps->hps);
     351        if (state->oldYInversion != 0)
     352        {
     353            ptl->y = state->oldYInversion - ptl->y;
     354            if (rct)
     355            {
     356                LONG temp = state->oldYInversion - rct->yBottom;
     357                rct->yBottom = state->oldYInversion - rct->yTop;
     358                rct->yTop = temp;
     359            }
     360
     361            GpiEnableYInversion(pHps->hps, 0);
     362
     363            state->restoreInversion = TRUE;
     364        }
     365#else
     366        // through the raw yInvert value
     367        if (pHps->yInvert > 0)
     368        {
     369            LONG temp = pHps->yInvert - rct->yBottom;
     370            rct->yBottom = pHps->yInvert - rct->yTop;
     371            rct->yTop = temp;
     372        }
     373#endif
     374    }
     375    else
     376    {
     377        // the complex case: append a matrix transformation that will flip the
     378        // text along the ptl's Y coordinate
     379        MATRIXLF mlf;
     380        mlf.fxM11 = MAKEFIXED(1, 0);
     381        mlf.fxM12 = 0;
     382        mlf.lM13  = 0;
     383        mlf.fxM21 = 0;
     384        mlf.fxM22 = MAKEFIXED(-1, 0);
     385        mlf.lM23  = 0;
     386        mlf.lM31  = 0;
     387        mlf.lM32  = ptl->y * 2;
     388        GpiSetDefaultViewMatrix(pHps->hps, 8, &mlf, TRANSFORM_ADD);
     389
     390        state->restoreMatrix = TRUE;
     391    }
     392}
     393
     394static void UncompensateTextInversion(CTISTATE *state)
     395{
     396    if (state->restoreInversion)
     397        GpiEnableYInversion(state->pHps->hps, state->oldYInversion);
     398    if (state->restoreMatrix)
     399        GpiSetDefaultViewMatrix(state->pHps->hps, 9, &state->mlf,
     400                                TRANSFORM_REPLACE);
     401}
     402//******************************************************************************
     403//******************************************************************************
    315404BOOL CFT2Module::Ft2CharStringPosAtA(HPS hps,PPOINTLOS2 ptl,PRECTLOS2 rct,ULONG flOptions,LONG lCount,LPCSTR pchString,CONST INT *alAdx, DWORD fuWin32Options)
    316405{
    317406    DWORD  ret;
    318407    USHORT sel;
    319 
    320     // All FreeType calls should be wrapped for saving FS
    321     if(pfnFt2CharStringPosAtA) {
     408    pDCData pHps;
     409
     410    pHps = (pDCData)OSLibGpiQueryDCData(hps);
     411
     412    CTISTATE ctiState;
     413    CompensateTextInversion(pHps, ptl, rct, &ctiState);
     414
     415    BOOL fallback = TRUE;
     416
     417    if(pfnFt2CharStringPosAtA)
     418    {
     419        // All FreeType calls should be wrapped for saving FS
    322420        sel  = RestoreOS2FS();
    323421        ret  = pfnFt2CharStringPosAtA(hps, ptl,rct,flOptions,lCount,pchString,alAdx, fuWin32Options);
    324422        SetFS(sel);
    325423        if(ret || (ret == FALSE && ERRORIDERROR(WinGetLastError(0)) != PMERR_FUNCTION_NOT_SUPPORTED))
    326             return ret;
    327     }
    328     //else fall back to GPI
    329     //NOTE: We don't support fuWin32Options in the fallback case
    330     pDCData pHps = (pDCData)OSLibGpiQueryDCData(hps);
    331     return OSLibGpiCharStringPosAt(pHps,ptl,rct,flOptions,lCount,pchString,alAdx);
     424            fallback = FALSE;
     425    }
     426
     427    if (fallback)
     428    {
     429        //else fall back to GPI
     430        //NOTE: We don't support fuWin32Options in the fallback case
     431        ret = OSLibGpiCharStringPosAt(pHps,ptl,rct,flOptions,lCount,pchString,alAdx);
     432    }
     433
     434    UncompensateTextInversion(&ctiState);
     435
     436    return ret;
    332437}
    333438//******************************************************************************
     
    337442    DWORD  ret;
    338443    USHORT sel;
    339 
    340     // All FreeType calls should be wrapped for saving FS
    341     if(pfnFt2CharStringPosAtW) {
     444    pDCData pHps;
     445
     446    pHps = (pDCData)OSLibGpiQueryDCData(hps);
     447
     448    CTISTATE ctiState;
     449    CompensateTextInversion(pHps, ptl, rct, &ctiState);
     450
     451    BOOL fallback = TRUE;
     452
     453    if (pfnFt2CharStringPosAtW)
     454    {
     455        // All FreeType calls should be wrapped for saving FS
    342456        sel  = RestoreOS2FS();
    343457        ret  = pfnFt2CharStringPosAtW(hps, ptl,rct,flOptions,lCount,pchString,alAdx, fuWin32Options);
    344458        SetFS(sel);
    345459        if(ret || (ret == FALSE && ERRORIDERROR(WinGetLastError(0)) != PMERR_FUNCTION_NOT_SUPPORTED))
    346             return ret;
    347     }
    348     //else fall back to GPI
    349     //NOTE: We don't support fuWin32Options in the fallback case
    350     int   len;
    351     LPSTR astring;
    352     LPINT lpDx = NULL;
    353 
    354     pDCData pHps = (pDCData)OSLibGpiQueryDCData(hps);
    355 
    356     len = WideCharToMultiByte( CP_ACP, 0, pchString, lCount, 0, 0, NULL, NULL );
    357     astring = (char *)malloc( len + 1 );
    358     lstrcpynWtoA(astring, pchString, len + 1 );
    359 
    360     if( IsDBCSEnv() && alAdx )
    361     {
    362         int i, j;
    363 
    364         lpDx = ( LPINT )malloc( len * sizeof( INT ));
    365         for( i = j = 0; i < len; i++, j++ )
     460            fallback = FALSE;
     461    }
     462
     463    if (fallback)
     464    {
     465        // fall back to GPI
     466        // NOTE: We don't support fuWin32Options in the fallback case
     467        int   len;
     468        LPSTR astring;
     469
     470        LPINT lpDx = NULL;
     471
     472        len = WideCharToMultiByte( CP_ACP, 0, pchString, lCount, 0, 0, NULL, NULL );
     473        astring = (char *)malloc( len + 1 );
     474        lstrcpynWtoA(astring, pchString, len + 1 );
     475
     476        if( IsDBCSEnv() && alAdx )
    366477        {
    367             lpDx[ i ] = alAdx[ j ];
    368             if( IsDBCSLeadByte( astring[ i ]))
    369                 lpDx[ ++i ] = 0;
    370         }
    371 
    372         alAdx = ( CONST INT * )lpDx;
    373     }
    374 
    375     ret = OSLibGpiCharStringPosAt(pHps,ptl,rct,flOptions,len,astring,alAdx);
    376 
    377     if( lpDx )
    378         free( lpDx );
    379 
    380     free(astring);
     478            int i, j;
     479
     480            lpDx = ( LPINT )malloc( len * sizeof( INT ));
     481            for( i = j = 0; i < len; i++, j++ )
     482            {
     483                lpDx[ i ] = alAdx[ j ];
     484                if( IsDBCSLeadByte( astring[ i ]))
     485                    lpDx[ ++i ] = 0;
     486            }
     487
     488            alAdx = ( CONST INT * )lpDx;
     489        }
     490
     491        ret = OSLibGpiCharStringPosAt(pHps,ptl,rct,flOptions,len,astring,alAdx);
     492
     493        if( lpDx )
     494            free( lpDx );
     495
     496        free(astring);
     497    }
     498
     499    UncompensateTextInversion(&ctiState);
    381500
    382501    return ret;
     
    387506                                 LPVOID lpvBuffer, DWORD cbData)
    388507{
    389     DWORD  ret; 
     508    DWORD  ret;
    390509    USHORT sel;
    391510
    392     // All FreeType calls should be wrapped for saving FS 
     511    // All FreeType calls should be wrapped for saving FS
    393512    if(pfnFt2GetFontData) {
    394513        sel  = RestoreOS2FS();
     
    396515        SetFS(sel);
    397516        if(ret || (ret == GDI_ERROR && ERRORIDERROR(WinGetLastError(0)) != PMERR_FUNCTION_NOT_SUPPORTED))
    398             return ret; 
     517            return ret;
    399518    }
    400519    //no fallback
     
    546665            lpResults->lpOrder[i] = i;
    547666
    548     // All FreeType calls should be wrapped for saving FS 
     667    // All FreeType calls should be wrapped for saving FS
    549668    if(pfnFt2GetCharacterPlacementW) {
    550669        sel  = RestoreOS2FS();
     
    566685
    567686               if(OSLibDevQueryCaps(pHps, OSLIB_CAPS_HORIZONTAL_RESOLUTION, 2, &alArray[0]) &&
    568                   alArray[0] != alArray[1]) 
     687                  alArray[0] != alArray[1])
    569688               {
    570689                   dprintf(("Different hor/vert resolutions (%d,%d)", alArray[0], alArray[1]));
     
    581700               }
    582701           }
    583            return ret; 
     702           return ret;
    584703        }
    585704    }
  • trunk/src/gdi32/text.cpp

    r10600 r21628  
    9595//******************************************************************************
    9696// todo: metafile support
    97 //#undef INVERT
    98 //#define INVERT_SETYINVERSION
    9997//******************************************************************************
    10098BOOL InternalTextOutAW(HDC hdc,int X,int Y,UINT fuOptions,
     
    135133  }
    136134
    137 #if defined(INVERT) && !defined(INVERT_SETYINVERSION)
    138   if(pHps->yInvert > 0) {
    139      Y = pHps->yInvert - Y;
    140   }
    141 #endif
    142 
    143 #ifdef INVERT_SETYINVERSION
    144   int oldyinv = GpiQueryYInversion(pHps->hps);
    145   Y = oldyinv - Y;
    146 #endif
    147 
    148135  // When using font association, the height of DBCS and SBCS chars may be different.
    149136  // In this case, background color make stair below chars
     
    181168        return TRUE;
    182169      }
    183 #ifndef INVERT
    184 #ifdef INVERT_SETYINVERSION
    185       if (oldyinv) {
    186           int temp       = oldyinv - pmRect.yTop;
    187           pmRect.yTop    = oldyinv - pmRect.yBottom;
    188           pmRect.yBottom = temp;
    189       }
    190 #else
    191       if (pHps->yInvert > 0) {
    192           int temp       = pHps->yInvert - pmRect.yTop;
    193           pmRect.yTop    = pHps->yInvert - pmRect.yBottom;
    194           pmRect.yBottom = temp;
    195       }
    196 #endif
    197 #endif
    198170
    199171      if (fuOptions & ETO_CLIPPED) flOptions |= CHSOS_CLIP;
     
    244216    }
    245217  }
    246 
    247 #ifdef INVERT_SETYINVERSION
    248   GpiEnableYInversion(pHps->hps, 0);
    249 #endif
    250218
    251219  if (lpDx)
     
    341309  if(hits == GPIOS_ERROR) {
    342310      dprintf(("InternalTextOutA: OSLibGpiCharStringPosAt returned GPIOS_ERROR"));
    343 #ifdef INVERT_SETYINVERSION
    344       GpiEnableYInversion(pHps->hps, oldyinv);
    345 #endif
    346311      return FALSE;
    347312  }
     
    356321      OSLibGpiSetCurrentPosition(pHps,&ptl);
    357322  }
    358 
    359 #ifdef INVERT_SETYINVERSION
    360   GpiEnableYInversion(pHps->hps, oldyinv);
    361 #endif
    362323
    363324  DIBSECTION_MARK_INVALID(hdc);
Note: See TracChangeset for help on using the changeset viewer.