Changeset 10373 for trunk/src


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

Update

Location:
trunk/src/gdi32
Files:
3 added
9 edited

Legend:

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

    r10167 r10373  
    1 /* $Id: blit.cpp,v 1.45 2003-07-16 10:46:16 sandervl Exp $ */
     1/* $Id: blit.cpp,v 1.46 2004-01-11 11:42:08 sandervl Exp $ */
    22
    33/*
     
    1717#include <winuser32.h>
    1818#include <dbglog.h>
     19#include "oslibgpi.h"
     20#include <dcdata.h>
    1921#include "dibsect.h"
    2022#include "rgbcvt.h"
     
    4850            rc  = dsect->BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
    4951                                nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, dwRop);
    50             return rc;
     52            goto blitdone;
    5153        }
    5254    }
    5355    rc = O32_StretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, dwRop);
    54     if(DIBSection::getSection() != NULL) {
    55         DIBSection *destdib = DIBSection::findHDC(hdcDest);
    56         if(destdib) {
    57             destdib->sync(hdcDest, nYOriginDest, nHeightDest);
    58         }
    59     }
     56
     57blitdone:
     58    DIBSECTION_MARK_INVALID(hdcDest);
     59
    6060    if(rc == FALSE) {
    6161        dprintf(("!WARNING!: GDI32: StretchBlt returned FALSE; last error %x", rc, GetLastError()));
     
    7878
    7979#ifdef DEBUG
    80       POINT point1, point2;
     80    POINT point1, point2;
    8181    GetViewportOrgEx(hdcDest, &point1);
    8282    GetViewportOrgEx(hdcSrc, &point2);
     
    9090        if(dsect)
    9191        {
    92             return dsect->BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc, nWidth, nHeight, dwRop);
     92            rc = dsect->BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc, nWidth, nHeight, dwRop);
     93            goto blitdone;
    9394        }
    9495    }
     
    9899    rc = O32_BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop);
    99100
    100     if(DIBSection::getSection() != NULL) {
    101         DIBSection *destdib = DIBSection::findHDC(hdcDest);
    102         if(destdib) {
    103             destdib->sync(hdcDest, nYDest, nHeight);
    104         }
    105     }
     101blitdone:
     102    DIBSECTION_MARK_INVALID(hdcDest);
    106103    return rc;
    107104}
     
    193190    }
    194191    if(startscan != 0 || lines != info->bmiHeader.biHeight) {
    195             dprintf(("WARNING: SetDIBitsToDevice startscan != 0 || lines != info->bmiHeader.biHeight"));
     192        dprintf(("WARNING: SetDIBitsToDevice startscan != 0 || lines != info->bmiHeader.biHeight"));
    196193        dprintf(("info bmp (%d,%d)", info->bmiHeader.biWidth, info->bmiHeader.biHeight));
    197194    }
     
    209206        result = info->bmiHeader.biHeight;
    210207
    211         DIBSection *destdib = DIBSection::findHDC(hdc);
    212         if(destdib) {
    213                 if(cx == info->bmiHeader.biWidth && cy == info->bmiHeader.biHeight &&
    214                    destdib->GetBitCount() == info->bmiHeader.biBitCount &&
    215                    destdib->GetBitCount() == 8)
    216                 {
    217                         destdib->sync(xDest, yDest, cx, cy, (PVOID)bits);
    218                 }
    219                 else    destdib->sync(hdc, yDest, cy);
    220         }
     208        DIBSECTION_MARK_INVALID(hdc);
    221209    }
    222210    dprintf(("GDI32: SetDIBitsToDevice hdc:%X xDest:%d yDest:%d, cx:%d, cy:%d, xSrc:%d, ySrc:%d, startscan:%d, lines:%d \nGDI32: bits 0x%X, info 0x%X, coloruse %d returned %d",
    223                  hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (LPVOID) bits, (PBITMAPINFO)info, coloruse, result));
     211              hdc, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, (LPVOID) bits, (PBITMAPINFO)info, coloruse, result));
    224212    dprintf(("GDI32: SetDIBitsToDevice %d %d %d %d %x %d", info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biPlanes, info->bmiHeader.biBitCount, info->bmiHeader.biCompression, info->bmiHeader.biSizeImage));
    225213
     
    358346    rc = O32_PatBlt(hdc,nXLeft,nYLeft,nWidth,nHeight,dwRop);
    359347    if(rc) {
    360         DIBSection *destdib = DIBSection::findHDC(hdc);
    361         if(destdib) {
    362                     destdib->sync(hdc, nYLeft, nHeight);
    363             }
     348        DIBSECTION_MARK_INVALID(hdc);
    364349    }
    365350    return(rc);
     
    367352//******************************************************************************
    368353//******************************************************************************
    369 BOOL WIN32API MaskBlt( HDC arg1, int arg2, int arg3, int arg4, int arg5, HDC   arg6, int arg7, int arg8, HBITMAP arg9, int arg10, int arg11, DWORD  arg12)
    370 {
    371     return O32_MaskBlt(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
     354BOOL WIN32API MaskBlt( HDC hdcDest, int arg2, int arg3, int arg4, int arg5, HDC hdcSrc, int arg7, int arg8, HBITMAP arg9, int arg10, int arg11, DWORD  arg12)
     355{
     356    BOOL ret;
     357
     358    DIBSECTION_CHECK_IF_DIRTY(hdcSrc);
     359
     360    ret = O32_MaskBlt(hdcDest, arg2, arg3, arg4, arg5, hdcSrc, arg7, arg8, arg9, arg10, arg11, arg12);
     361    if(ret) {
     362        DIBSECTION_MARK_INVALID(hdcDest);
     363    }
     364    return ret;
    372365}
    373366//******************************************************************************
     
    426419        //Open32 always returns height of bitmap (regardless of how many scanlines were copied)
    427420        if(rc != heightSrc && rc != infoLoc->bmiHeader.biHeight) {
    428                     dprintf(("StretchDIBits failed with rc %x", rc));
     421            dprintf(("StretchDIBits failed with rc %x", rc));
    429422        }
    430             else {
    431                     rc = heightSrc;
    432 
    433                     DIBSection *destdib = DIBSection::findHDC(hdc);
    434                     if(destdib) {
    435                         if(widthDst == widthSrc && heightDst == heightSrc &&
    436                             destdib->GetBitCount() == infoLoc->bmiHeader.biBitCount &&
    437                             destdib->GetBitCount() == 8)
    438                 {
    439                                     destdib->sync(xDst, yDst, widthDst, heightDst, (PVOID)bits);
    440                             }
    441                             else        destdib->sync(hdc, yDst, heightDst);
    442                     }
    443             }
     423        else {
     424            rc = heightSrc;
     425
     426            DIBSECTION_MARK_INVALID(hdc);
     427        }
    444428   
    445429        return rc;
     
    489473
    490474    rc = O32_StretchDIBits(hdc, xDst, yDst, widthDst, heightDst, xSrc, ySrc,
    491                              widthSrc, heightSrc, (void *)bits,
    492                              (PBITMAPINFO)info, wUsage, dwRop);
     475                           widthSrc, heightSrc, (void *)bits,
     476                           (PBITMAPINFO)info, wUsage, dwRop);
    493477
    494478    if(compression == BI_BITFIELDS) {
     
    505489            rc = heightSrc;
    506490
    507             DIBSection *destdib = DIBSection::findHDC(hdc);
    508             if(destdib) {
    509                 if(widthDst == widthSrc && heightDst == heightSrc &&
    510                     destdib->GetBitCount() == info->bmiHeader.biBitCount &&
    511                     destdib->GetBitCount() == 8)
    512             {
    513                              destdib->sync(xDst, yDst, widthDst, heightDst, (PVOID)bits);
    514                     }
    515                     else destdib->sync(hdc, yDst, heightDst);
    516             }
     491            DIBSECTION_MARK_INVALID(hdc);
    517492    }
    518493
     
    526501                           const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
    527502{
    528 
    529503    if(info->bmiHeader.biHeight < 0) {
    530504        // upside down
     
    563537int WIN32API SetStretchBltMode( HDC arg1, int  arg2)
    564538{
     539#ifdef DEBUG
    565540    if(DIBSection::getSection() != NULL)
    566541    {
     
    571546        }
    572547    }
     548#endif
    573549    return O32_SetStretchBltMode(arg1, arg2);
    574550}
  • trunk/src/gdi32/dbglocal.cpp

    r9429 r10373  
    1 /* $Id: dbglocal.cpp,v 1.9 2002-11-26 10:53:07 sandervl Exp $ */
     1/* $Id: dbglocal.cpp,v 1.10 2004-01-11 11:42:08 sandervl Exp $ */
    22
    33/*
     
    4343"printer",
    4444"icm",
    45 "trace"
     45"trace",
     46"fontres",
     47"devcontext"
    4648};
    4749//******************************************************************************
  • trunk/src/gdi32/dbglocal.h

    r9429 r10373  
    1 /* $Id: dbglocal.h,v 1.8 2002-11-26 10:53:07 sandervl Exp $ */
     1/* $Id: dbglocal.h,v 1.9 2004-01-11 11:42:09 sandervl Exp $ */
    22
    33/*
     
    4242#define DBG_icm             20
    4343#define DBG_trace           21
    44 #define DBG_MAXFILES        22
     44#define DBG_fontres         22
     45#define DBG_devcontext      23
     46#define DBG_MAXFILES        24
    4547
    4648extern USHORT DbgEnabledGDI32[DBG_MAXFILES];
  • trunk/src/gdi32/dbgwrap.cpp

    r10329 r10373  
    9090DEBUGWRAP20(IntersectClipRect)
    9191DEBUGWRAP8(GetRgnBox)
    92 DEBUGWRAP12(GetRandomRgn)
    9392NODEF_DEBUGWRAP8(GetMetaRgn)
    9493DEBUGWRAP8(GetClipRgn)
    9594DEBUGWRAP20(FrameRgn)
    9695DEBUGWRAP12(FillRgn)
     96DEBUGWRAP12(GetRandomRgn)
    9797DEBUGWRAP12(ExtSelectClipRgn)
    9898DEBUGWRAP8(EqualRgn)
     
    214214DEBUGWRAP_LVL2_4(GetObjectType)
    215215DEBUGWRAP12(GetObjectW)
    216 DEBUGWRAP4(GetStockObject)
     216DEBUGWRAP_LVL2_4(GetStockObject)
    217217DEBUGWRAP_LVL2_8(SelectObject)
    218218NODEF_DEBUGWRAP8(SetObjectOwner)
     
    295295DEBUGWRAP4(CreateColorSpaceA)
    296296DEBUGWRAP4(CreateColorSpaceW)
    297 DEBUGWRAP4(CreateCompatibleDC)
    298 DEBUGWRAP16(CreateDCA)
    299 DEBUGWRAP16(CreateDCW)
    300297DEBUGWRAP8(CreateDIBPatternBrush)
    301298DEBUGWRAP8(CreateDIBPatternBrushPt)
    302299DEBUGWRAP8(CreateHatchBrush)
    303 DEBUGWRAP16(CreateICA)
    304 DEBUGWRAP16(CreateICW)
    305300DEBUGWRAP4(CreatePatternBrush)
    306301DEBUGWRAP12(CreatePen)
     
    309304DEBUGWRAP12(DPtoLP)
    310305DEBUGWRAP4(DeleteColorSpace)
    311 DEBUGWRAP4(DeleteDC)
    312306DEBUGWRAP16(DescribePixelFormat)
    313307//;    DeviceCapabilitiesEx       = _DeviceCapabilitiesEx@??    @177
     
    356350NODEF_DEBUGWRAP8(GetDeviceGammaRamp)
    357351DEBUGWRAP12(GetKerningPairsA)
    358 DEBUGWRAP12(GetKerningPairsW)
    359352NODEF_DEBUGWRAP12(GetLogColorSpaceA)
    360353NODEF_DEBUGWRAP12(GetLogColorSpaceW)
     
    423416DEBUGWRAP4(UpdateColors)
    424417DEBUGWRAP4(WidenPath)
     418
     419
     420#undef DBG_LOCALLOG
     421#define DBG_LOCALLOG    DBG_devcontext
     422
     423DEBUGWRAP4(CreateCompatibleDC)
     424DEBUGWRAP16(CreateDCA)
     425DEBUGWRAP16(CreateDCW)
     426DEBUGWRAP16(CreateICA)
     427DEBUGWRAP16(CreateICW)
     428DEBUGWRAP4(DeleteDC)
  • trunk/src/gdi32/dibitmap.cpp

    r10167 r10373  
    1 /* $Id: dibitmap.cpp,v 1.41 2003-07-16 10:46:17 sandervl Exp $ */
     1/* $Id: dibitmap.cpp,v 1.42 2004-01-11 11:42:10 sandervl Exp $ */
    22
    33/*
     
    66 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
    77 * Copyright 1998 Patrick Haller
     8 * Copyright 2002-2003 Innotek Systemberatung GmbH (sandervl@innotek.de)
    89 *
    910 * Project Odin Software License can be found in LICENSE.TXT
     
    320321    if(dsect)
    321322    {
    322         return(dsect->SetDIBColorTable(uStartIndex, cEntries, pColors));
     323         return(dsect->SetDIBColorTable(uStartIndex, cEntries, pColors));
    323324    }
    324325    else return(0);
     
    326327//******************************************************************************
    327328//******************************************************************************
    328 LONG WIN32API GetBitmapBits( HBITMAP hBitmap, LONG arg2, PVOID  arg3)
     329LONG WIN32API GetBitmapBits( HBITMAP hBitmap, LONG arg2, PVOID lpvBits)
    329330{
    330331    dprintf(("GDI32: GetBitmapBits %x", hBitmap));
    331     return O32_GetBitmapBits(hBitmap, arg2, arg3);
     332
     333    if(lpvBits)
     334    {
     335        DIBSECTION_CHECK_IF_DIRTY_BMP(hBitmap);
     336    }
     337    return O32_GetBitmapBits(hBitmap, arg2, lpvBits);
    332338}
    333339//******************************************************************************
     
    335341LONG WIN32API SetBitmapBits( HBITMAP hBitmap, LONG arg2, const VOID *  arg3)
    336342{
     343    LONG ret;
     344
    337345    dprintf(("GDI32: SetBitmapBits %x", hBitmap));
    338     return O32_SetBitmapBits(hBitmap, (DWORD)arg2, arg3);
     346    ret = O32_SetBitmapBits(hBitmap, (DWORD)arg2, arg3);
     347    DIBSECTION_MARK_INVALID_BMP(hBitmap);
     348    return ret;
    339349}
    340350//******************************************************************************
     
    364374    dprintf(("GDI32: GetDIBits %x %x %d %d %x %x (biBitCount %d) %d", hdc, hBitmap, uStartScan, cScanLines, lpvBits, lpbi, lpbi->bmiHeader.biBitCount, uUsage));
    365375
    366 #if 0
    367     if(lpvBits && DIBSection::getSection() != NULL)
    368     {
    369         DIBSection *dsect;
    370 
    371         dsect = DIBSection::findObj(hBitmap);
    372         if(dsect) {
    373              char *bmpBits = dsect->GetDIBObject();
    374 
    375              if(lpbi->bmiHeader.biBitCount == dsect->GetBitCount() &&
    376                 lpbi->bmiHeader.biWidth > 0)
    377              {
    378                  LONG lLineByte;
    379 
    380                  dprintf(("Quick copy from DIB section memory"));
    381                  lLineByte = DIB_GetDIBWidthBytes(lpbi->bmiHeader.biWidth, lpbi->bmiHeader.biBitCount);
    382                  
    383                  memcpy(lpvBits, bmpBits+(uStartScan*lLineByte), cScanLines*lLineByte);
    384                  return cScanLines;
    385              }
    386         }
    387     }
    388 #endif
     376    if(lpvBits)
     377    {
     378        DIBSECTION_CHECK_IF_DIRTY_BMP(hBitmap);
     379    }
    389380
    390381    //SvL: WGSS screws up the DC if it's a memory DC
     
    397388    }
    398389    if(pHps->isMemoryPS) {
    399           hdcMem = CreateCompatibleDC(0);
    400     }
    401     else  hdcMem = hdc;
     390         hdcMem = CreateCompatibleDC(0);
     391    }
     392    else hdcMem = hdc;
    402393
    403394    if(lpvBits) {
     
    547538        ret = O32_SetBitmapBits(hBitmap, pBitmapInfo->bmiHeader.biSizeImage, newpix);
    548539
     540        DIBSECTION_MARK_INVALID_BMP(hBitmap);
     541
    549542        free(newpix);
    550543        return ret;
     
    624617    if(newbits) free(newbits);
    625618
    626     if(DIBSection::getSection() != NULL)
    627     {
    628         DIBSection *dsect;
    629 
    630         dsect = DIBSection::findObj(hBitmap);
    631         if(dsect) {
    632              HBITMAP hBmpOld = SelectObject(hdc, hBitmap);
    633              dsect->sync(hdc, 0, dsect->GetHeight());
    634              SelectObject(hdc, hBmpOld);
    635         }
    636     }
     619    DIBSECTION_MARK_INVALID_BMP(hBitmap);
    637620
    638621    return ret;
  • trunk/src/gdi32/dibsect.cpp

    r10167 r10373  
    1 /* $Id: dibsect.cpp,v 1.67 2003-07-16 10:46:17 sandervl Exp $ */
     1/* $Id: dibsect.cpp,v 1.68 2004-01-11 11:42:10 sandervl Exp $ */
    22
    33/*
     
    66 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
    77 * Copyright 1998 Patrick Haller
     8 * Copyright 2002-2003 Innotek Systemberatung GmbH (sandervl@innotek.de)
    89 *
    910 * Project Odin Software License can be found in LICENSE.TXT
    1011 *
    11  * NOTE:
    12  * This is not a complete solution for CreateDIBSection, but enough for Quake 2!
     12 * Basic GPI object and bitmap data synchronization:
     13 *
     14 * - CreateDIBSection:
     15 *      register a memory range for exception notification
     16 *      set to read/commit during creation
     17 *
     18 * - if(exception)
     19 *      if(invalid)
     20 *         sync and set to commit/read, clear invalid flag
     21 *      if(write violation)
     22 *         make as dirty and set range to read/write
     23 *
     24 * - before GDI operation
     25 *       if(dirty)
     26 *           flush (set bitmap bits), clear dirty flag, set range to readonly
     27 *
     28 * - after GDI operation
     29 *       set invalid flag, set range to invalid
     30 *
     31 * - GdiFlush:
     32 *       NOP
     33 *
     34 * Should probably detect partial changes to avoid having to sync the entire
     35 * DIB section each time something minor changes.
     36 *
     37 * Might get a little bit more complicated when the application gives us a memory
     38 * mapped file handle. (although we can change the protection flags of aliased pages)
    1339 *
    1440 */
     
    2753#include "oslibgpi.h"
    2854#include "rgbcvt.h"
     55#include <memmap.h>
    2956
    3057#define DBG_LOCALLOG  DBG_dibsect
    3158#include "dbglocal.h"
    3259
    33 
    34 //******************************************************************************
    35 //******************************************************************************
    36 DIBSection::DIBSection(BITMAPINFOHEADER_W *pbmi, char *pColors, DWORD iUsage, DWORD hSection, DWORD dwOffset, DWORD handle, int fFlip)
     60static BOOL WIN32API DIBExceptionNotify(LPVOID lpBase, ULONG offset, BOOL fWriteAccess,
     61                                        DWORD dwSize, DWORD dwUserData);
     62
     63
     64//******************************************************************************
     65//******************************************************************************
     66DIBSection::DIBSection(BITMAPINFOHEADER_W *pbmi, char *pColors, DWORD iUsage, DWORD hSection, DWORD dwOffset, HBITMAP hBitmap, int fFlip)
    3767                : bmpBits(NULL), pOS2bmp(NULL), next(NULL), bmpBitsDblBuffer(NULL),
    38                   hdc(0), hwndParent(0)
     68                  hdc(0), hwndParent(0), fDirty(FALSE), fInvalid(FALSE), dwSize(0)
    3969{
    4070 int  palsize=0;
     
    90120   }
    91121   if(!bmpBits) {
    92         DosAllocMem((PPVOID)&bmpBits, bmpsize*pbmi->biHeight, PAG_READ|PAG_WRITE|PAG_COMMIT);
    93    }
    94    memset(bmpBits, 0, bmpsize*pbmi->biHeight);
     122        APIRET rc = DosAllocMem((PPVOID)&bmpBits, bmpsize*pbmi->biHeight, PAG_READ|PAG_COMMIT);
     123        if(rc) {
     124            dprintf(("DosAllocMem failed with %d", rc));
     125            DebugInt3();
     126        }
     127        if(MMAP_RegisterMemoryRange(DIBExceptionNotify, bmpBits, bmpsize*pbmi->biHeight, hBitmap) == FALSE)
     128        {
     129            dprintf(("MMAP_RegisterMemoryRange failed!!"));
     130            DebugInt3();
     131        }
     132        dwSize = bmpsize*pbmi->biHeight;
     133   }
     134   else memset(bmpBits, 0, bmpsize*pbmi->biHeight);
    95135
    96136   pOS2bmp = (BITMAPINFO2 *)malloc(os2bmphdrsize);
     
    111151   }
    112152   pOS2bmp->cbImage       = pbmi->biSizeImage;
    113    dprintf(("handle                 %x", handle));
     153   dprintf(("hBitmap                %x", hBitmap));
    114154   dprintf(("pOS2bmp->cx            %d\n", pOS2bmp->cx));
    115155   dprintf(("pOS2bmp->cy            %d\n", pOS2bmp->cy));
     
    169209   }
    170210
    171    this->handle = handle;
     211   this->hBitmap = hBitmap;
    172212   this->iUsage = iUsage;
    173213
     
    197237DIBSection::~DIBSection()
    198238{
    199    dprintf(("Delete DIBSection %x", handle));
     239   dprintf(("Delete DIBSection %x", hBitmap));
    200240
    201241   if(hSection) {
    202         UnmapViewOfFile(bmpBits);
    203    }
    204    else
    205    if(bmpBits)
    206         DosFreeMem(bmpBits);
     242       UnmapViewOfFile(bmpBits);
     243   }
     244   else
     245   {
     246       if(MMAP_UnregisterMemoryRange(bmpBits) == FALSE)
     247       {
     248           dprintf(("MMAP_UnregisterMemoryRange failed!!"));
     249           DebugInt3();
     250       }
     251       if(bmpBits)
     252           DosFreeMem(bmpBits);
     253   }
    207254
    208255   if(bmpBitsDblBuffer)
    209         DosFreeMem(bmpBitsDblBuffer);
     256       DosFreeMem(bmpBitsDblBuffer);
    210257
    211258   if(pOS2bmp)
    212         free(pOS2bmp);
     259       free(pOS2bmp);
    213260
    214261   lock();
    215262   if(section == this)
    216263   {
    217      section = this->next;
     264       section = this->next;
    218265   }
    219266   else
    220267   {
    221      DIBSection *dsect = section;
    222 
    223      while(dsect->next != this)
    224      {
    225        dsect = dsect->next;
    226      }
    227      dsect->next = this->next;
     268       DIBSection *dsect = section;
     269
     270       while(dsect->next != this)
     271       {
     272           dsect = dsect->next;
     273       }
     274       dsect->next = this->next;
    228275   }
    229276   unlock();
    230 }
    231 //******************************************************************************
    232 //******************************************************************************
    233 int DIBSection::SetDIBits(HDC hdc, HBITMAP hbitmap, UINT startscan, UINT
    234                           lines, const VOID *bits, BITMAPINFOHEADER_W *pbmi,
    235                           UINT coloruse)
    236 {
    237   lines = (int)lines >= 0 ? (int)lines : (int)-lines;
    238   int  palsize=0;
    239 
    240   bmpsize = pbmi->biWidth;
    241   os2bmphdrsize = sizeof(BITMAPINFO2);
    242 
    243   switch(pbmi->biBitCount)
    244   {
    245     case 1:
    246       bmpsize = ((bmpsize + 31) & ~31) / 8;
    247       palsize = ((1 << pbmi->biBitCount))*sizeof(RGB2);
    248       os2bmphdrsize += palsize;
    249       break;
    250     case 4:
    251       bmpsize = ((bmpsize + 7) & ~7) / 2;
    252       palsize = ((1 << pbmi->biBitCount))*sizeof(RGB2);
    253       os2bmphdrsize += palsize;
    254       break;
    255     case 8:
    256       palsize = ((1 << pbmi->biBitCount))*sizeof(RGB2);
    257       os2bmphdrsize += palsize;
    258       bmpsize = (bmpsize + 3) & ~3;
    259       break;
    260     case 16:
    261       bmpsize *= 2;
    262       bmpsize = (bmpsize + 3) & ~3;
    263       break;
    264     case 24:
    265       bmpsize *= 3;
    266       bmpsize = (bmpsize + 3) & ~3;
    267       break;
    268     case 32:
    269       bmpsize *= 4;
    270       break;
    271    }
    272 
    273    //SvL: TODO: Correct??
    274    if(!hSection && pOS2bmp->cx != pbmi->biWidth && pOS2bmp->cy != pbmi->biHeight &&
    275       pOS2bmp->cBitCount != pbmi->biBitCount)
    276    {
    277         char *oldbits = bmpBits;
    278         int oldsize = dibinfo.dsBm.bmWidthBytes * dibinfo.dsBm.bmHeight;
    279 
    280         DosAllocMem((PPVOID)&bmpBits, bmpsize*pbmi->biHeight, PAG_READ|PAG_WRITE|PAG_COMMIT);
    281         memcpy(bmpBits, oldbits, min(oldsize, bmpsize*pbmi->biHeight));
    282         DosFreeMem(oldbits);
    283    }
    284    pOS2bmp    = (BITMAPINFO2 *)realloc(pOS2bmp, os2bmphdrsize);
    285    pOS2bmp->cbFix         = sizeof(BITMAPINFO2) - sizeof(RGB2);
    286    pOS2bmp->cx            = pbmi->biWidth;
    287    pOS2bmp->cy            = pbmi->biHeight;
    288    pOS2bmp->cPlanes       = pbmi->biPlanes;
    289    pOS2bmp->cBitCount     = pbmi->biBitCount;
    290    pOS2bmp->ulCompression = pbmi->biCompression; //same as OS/2 (uncompressed, rle8, rle4)
    291    //SvL: Ignore BI_BITFIELDS_W type (GpiDrawBits fails otherwise)
    292    if(pOS2bmp->ulCompression == BI_BITFIELDS_W) {
    293         pOS2bmp->ulCompression = 0;
    294    }
    295    pOS2bmp->cbImage       = pbmi->biSizeImage;
    296 
    297    // clear DIBSECTION structure
    298    memset(&dibinfo, 0, sizeof(dibinfo));
    299 
    300    // copy BITMAPINFOHEADER data into DIBSECTION structure
    301    memcpy(&dibinfo.dsBmih, pbmi, sizeof(*pbmi));
    302    dibinfo.dsBm.bmType      = 0;
    303    dibinfo.dsBm.bmWidth     = pbmi->biWidth;
    304    dibinfo.dsBm.bmHeight    = pbmi->biHeight;
    305    dibinfo.dsBm.bmWidthBytes= bmpsize;
    306    dibinfo.dsBm.bmPlanes    = pbmi->biPlanes;
    307    dibinfo.dsBm.bmBitsPixel = pbmi->biBitCount;
    308    dibinfo.dsBm.bmBits      = bmpBits;
    309 
    310    dibinfo.dshSection       = hSection;
    311    dibinfo.dsOffset         = dwOffset;
    312 
    313    if(coloruse == DIB_PAL_COLORS || pbmi->biBitCount <= 8)
    314    {
    315         dibinfo.dsBitfields[0] = dibinfo.dsBitfields[1] = dibinfo.dsBitfields[2] = 0;
    316    }
    317    else {
    318         char *pColors = (char *)pbmi + 1;
    319 
    320         switch(pbmi->biBitCount)
    321         {
    322            case 16:
    323                 dibinfo.dsBitfields[0] = (pbmi->biCompression == BI_BITFIELDS_W) ? *(DWORD *)pColors : 0x7c00;
    324                 dibinfo.dsBitfields[1] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 1) : 0x03e0;
    325                 dibinfo.dsBitfields[2] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 2) : 0x001f;
    326                 break;
    327 
    328            case 24:
    329            case 32:
    330                 dibinfo.dsBitfields[0] = (pbmi->biCompression == BI_BITFIELDS_W) ? *(DWORD *)pColors       : 0xff0000;
    331                 dibinfo.dsBitfields[1] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 1) : 0x00ff00;
    332                 dibinfo.dsBitfields[2] = (pbmi->biCompression == BI_BITFIELDS_W) ? *((DWORD *)pColors + 2) : 0x0000ff;
    333                 if(dibinfo.dsBitfields[0] != 0xff0000 && dibinfo.dsBitfields[1] != 0xff00 && dibinfo.dsBitfields[2] != 0xff) {
    334                     dprintf(("DIBSection: unsupported bitfields for 32 bits bitmap!!"));
    335                 }
    336                 break;
    337         }
    338         dprintf(("BI_BITFIELDS_W %x %x %x", dibinfo.dsBitfields[0], dibinfo.dsBitfields[1], dibinfo.dsBitfields[2]));
    339    }
    340 
    341    //double buffer for rgb 555 dib sections (for conversion) or flipped sections
    342    if(dibinfo.dsBitfields[1] == 0x03e0 || (fFlip & FLIP_VERT)) {
    343         if(bmpBitsDblBuffer) {
    344             DosFreeMem(bmpBitsDblBuffer);
    345         }
    346         DosAllocMem((PPVOID)&bmpBitsDblBuffer, dibinfo.dsBm.bmWidthBytes*pbmi->biHeight, PAG_READ|PAG_WRITE|PAG_COMMIT);
    347    }
    348 
    349    dprintf(("DIBSection::SetDIBits (%d,%d), %d %d", pbmi->biWidth, pbmi->biHeight, pbmi->biBitCount, pbmi->biCompression));
    350    if(palsize) {
    351         SetDIBColorTable(0, (pbmi->biClrUsed) ? pbmi->biClrUsed : (1 << pbmi->biBitCount), (RGBQUAD *)(pbmi+1));
    352    }
    353 
    354    if(bits)
    355    {
    356       if(pOS2bmp->ulCompression == BCA_UNCOMP) {
    357           int size = bmpsize*lines;
    358           memcpy(bmpBits+bmpsize*startscan, bits, size);
    359       }
    360       else {
    361           dprintf(("Compressed image!!"));
    362           if(startscan != 0) {
    363                dprintf(("WARNING: Compressed image & startscan != 0!!!!"));
    364           }
    365           memcpy(bmpBits, bits, pbmi->biSizeImage);
    366       }
    367    }
    368    return(lines);
    369277}
    370278//******************************************************************************
     
    472380
    473381  dprintf(("DIBSection::BitBlt %x %X (hps %x) %x to(%d,%d)(%d,%d) from (%d,%d)(%d,%d) rop %x flip %x",
    474           handle, hdcDest, hps, hwndDest, nXdest, nYdest, nDestWidth, nDestHeight,
     382          hBitmap, hdcDest, hps, hwndDest, nXdest, nYdest, nDestWidth, nDestHeight,
    475383          nXsrc, nYsrc, nSrcWidth, nSrcHeight, Rop, fFlip));
     384
     385  //shortcut; better to sync it here instead of in the exception handler
     386  //(pages touched inside PMGPI)
     387  if(isInvalid()) {
     388      sync();
     389  }
    476390
    477391  if(hwndDest) {
     
    637551  }
    638552  if(rc == GPI_OK) {
    639         DIBSection *destdib = DIBSection::findHDC(hdcDest);
    640         if(destdib) {
    641             destdib->sync(hps, nYdest, nDestHeight, FALSE);
    642         }
    643553#ifdef INVERT
    644554        //restore old y inversion height
     
    664574 char  *destBuf;
    665575
    666   dprintf(("Sync destination dibsection %x (%x) (%d,%d) flip %d", handle, hdc, nYdest, nDestHeight, fFlip));
     576  dprintf(("Sync destination dibsection %x (%x) (%d,%d) flip %d", hBitmap, hdc, nYdest, nDestHeight, fFlip));
    667577
    668578  BITMAPINFO2 *tmphdr = (BITMAPINFO2 *)malloc(os2bmphdrsize);
     
    692602  if(fFlip & FLIP_VERT) {
    693603#endif
     604        //origin is top left, so no y conversion is necessary
    694605        destBuf = bmpBitsDblBuffer + nYdest*dibinfo.dsBm.bmWidthBytes;
    695606
     
    729640        tmphdr->cbImage = dibinfo.dsBm.bmHeight*dibinfo.dsBm.bmWidthBytes;
    730641
    731         destBuf = GetDIBObject() + nYdest*dibinfo.dsBm.bmWidthBytes;
    732 
     642        //origin is bottom left, nYdest is based on top left coordinate system
    733643#ifdef INVERT
    734644        int dest = dibinfo.dsBm.bmHeight - nYdest - nDestHeight;
     
    736646        int dest = nYdest;
    737647#endif
    738         rc = GpiQueryBitmapBits(hdc, nYdest, nDestHeight, destBuf,
     648
     649        destBuf = GetDIBObject() + dest*dibinfo.dsBm.bmWidthBytes;
     650
     651        rc = GpiQueryBitmapBits(hdc, dest, nDestHeight, destBuf,
    739652                                tmphdr);
    740653        if(rc == GPI_ALTERROR) {
     
    769682#endif
    770683
     684}
     685//******************************************************************************
     686//******************************************************************************
     687void DIBSection::flush(HDC hdc, DWORD nYdest, DWORD nDestHeight, BOOL orgYInversion)
     688{
     689 APIRET rc;
     690 char  *destBuf;
     691
     692  dprintf(("flush destination dibsection %x (%x) (%d,%d) flip %d", hBitmap, hdc, nYdest, nDestHeight, fFlip));
     693
     694#ifdef INVERT
     695  int oldyinversion = 0;
     696  if(orgYInversion == TRUE) {
     697      oldyinversion = GpiQueryYInversion(hdc);
     698      dprintf(("Flush destination dibsection: hdc y inversion = %d", oldyinversion));
     699      if(oldyinversion != 0) {
     700#ifdef DEBUG
     701          POINT point;
     702          GetViewportOrgEx(hdc, &point);
     703          dprintf(("Viewport origin (%d,%d)", point.x, point.y));
     704#endif
     705          GpiEnableYInversion(hdc, 0);
     706      }
     707  }
     708#else
     709  dprintf(("flush destination dibsection: hdc y inversion = %d", GpiQueryYInversion(hdc)));
     710#endif
     711
     712#ifndef INVERT
     713  if(!(fFlip & FLIP_VERT)) {
     714#else
     715  if(fFlip & FLIP_VERT) {
     716#endif
     717        //origin is top left, so no y conversion is necessary
     718        destBuf = bmpBitsDblBuffer + nYdest*dibinfo.dsBm.bmWidthBytes;
     719
     720        //SvL: cbImage can be too small for compressed images; GpiQueryBitmapBits
     721        //     will fail in that case (CoolEdit 2000). Perhaps because the returned
     722        //     compressed image is larger than the original.
     723        //     Use uncompressed size instead
     724        //     NOTE: The correct size will be returned by GpiQueryBitmapBits
     725        pOS2bmp->cbImage = dibinfo.dsBm.bmHeight*dibinfo.dsBm.bmWidthBytes;
     726
     727        //manually reverse bitmap data
     728        char *src = GetDIBObject() + (nYdest+nDestHeight-1)*dibinfo.dsBm.bmWidthBytes;
     729        char *dst = destBuf;
     730        for(int i=0;i<nDestHeight;i++) {
     731            memcpy(dst, src, dibinfo.dsBm.bmWidthBytes);
     732            dst += dibinfo.dsBm.bmWidthBytes;
     733            src -= dibinfo.dsBm.bmWidthBytes;
     734        }
     735
     736        if(dibinfo.dsBitfields[1] == 0x3E0) {//RGB 555?
     737            dprintf(("DIBSection::flush: convert RGB 565 to RGB 555"));
     738
     739            pRGB565to555((WORD *)destBuf, (WORD *)destBuf, (nDestHeight*dibinfo.dsBm.bmWidthBytes)/sizeof(WORD));
     740        }
     741
     742#ifdef INVERT
     743        int dest = dibinfo.dsBm.bmHeight - nYdest - nDestHeight;
     744#else
     745        int dest = nYdest;
     746#endif
     747        rc = GpiSetBitmapBits(hdc, dest, nDestHeight, destBuf,
     748                              pOS2bmp);
     749        if(rc == GPI_ALTERROR) {
     750            dprintf(("ERROR: GpiQueryBitmapBits failed with %x", WinGetLastError(0)));
     751        }
     752
     753  }
     754  else {
     755        //SvL: cbImage can be too small for compressed images; GpiQueryBitmapBits
     756        //     will fail in that case (CoolEdit 2000). Perhaps because the returned
     757        //     compressed image is larger than the original.
     758        //     Use uncompressed size instead
     759        //     NOTE: The correct size will be returned by GpiQueryBitmapBits
     760        pOS2bmp->cbImage = dibinfo.dsBm.bmHeight*dibinfo.dsBm.bmWidthBytes;
     761
     762        //origin is bottom left, nYdest is based on top left coordinate system
     763#ifdef INVERT
     764        int dest = dibinfo.dsBm.bmHeight - nYdest - nDestHeight;
     765#else
     766        int dest = nYdest;
     767#endif
     768
     769        destBuf = GetDIBObject() + dest*dibinfo.dsBm.bmWidthBytes;
     770
     771        if(dibinfo.dsBitfields[1] == 0x3E0) {//RGB 555?
     772            dprintf(("DIBSection::flush: convert RGB 565 to RGB 555"));
     773
     774            pRGB565to555((WORD *)bmpBitsDblBuffer, (WORD *)destBuf, (nDestHeight*dibinfo.dsBm.bmWidthBytes)/sizeof(WORD));
     775            destBuf = bmpBitsDblBuffer;
     776        }
     777
     778        rc = GpiSetBitmapBits(hdc, dest, nDestHeight, destBuf,
     779                              pOS2bmp);
     780        if(rc == GPI_ALTERROR) {
     781            dprintf(("ERROR: GpiQueryBitmapBits failed with %x", WinGetLastError(0)));
     782        }
     783#ifdef DEBUG_PALETTE
     784        if(rc != GPI_ALTERROR && pOS2bmp->cBitCount <= 8) {
     785            for(int i=0;i<(1<<pOS2bmp->cBitCount);i++)
     786            {
     787                dprintf2(("Index %d : 0x%08X\n",i, *((ULONG*)(&pOS2bmp->argbColor[i])) ));
     788            }
     789        }
     790#endif
     791  }
     792  if(rc != nDestHeight) {
     793      dprintf(("!WARNING!: GpiQueryBitmapBits returned %d instead of %d scanlines", rc, nDestHeight));
     794  }
     795
     796#ifdef INVERT
     797  if(oldyinversion) GpiEnableYInversion(hdc, oldyinversion);
     798#endif
     799
     800}
     801//******************************************************************************
     802//Mark the DIB section as invalid; a subsequent read or write access must
     803//cause a pagefault
     804//******************************************************************************
     805void DIBSection::setInvalid()
     806{
     807    if(!fInvalid) {
     808        dprintf(("DIBSection::setInvalid %x (%x)", GetBitmapHandle(), GetDIBObject()));
     809        APIRET rc = DosSetMem(bmpBits, dwSize, PAG_DECOMMIT);
     810        if(rc) {
     811            dprintf(("DIBSection::setInvalid: DosSetMem failed with %d!!", rc));
     812            DebugInt3();
     813        }
     814        fInvalid = TRUE;
     815    }
     816}
     817//******************************************************************************
     818//******************************************************************************
     819void DIBSection::flush()
     820{
     821    if(pOS2bmp == NULL) {
     822        DebugInt3();
     823        return;
     824    }
     825    if(hdc == 0) {
     826         HBITMAP hOldBmp;
     827         HDC hdcFlush = CreateCompatibleDC(0);
     828
     829         hOldBmp = SelectObject(hdcFlush, hBitmap);
     830         flush(hdcFlush, 0, pOS2bmp->cy);
     831
     832         SelectObject(hdcFlush, hOldBmp);
     833         DeleteDC(hdcFlush);
     834    }
     835    else flush(hdc, 0, pOS2bmp->cy);
     836
     837    APIRET rc = DosSetMem(bmpBits, dwSize, PAG_READ);
     838    if(rc) {
     839        dprintf(("DIBSection::flush: DosSetMem failed with %d!!", rc));
     840        DebugInt3();
     841    }
     842    fDirty = FALSE;
     843}
     844//******************************************************************************
     845//******************************************************************************
     846void DIBSection::sync()
     847{
     848    if(pOS2bmp == NULL) {
     849        DebugInt3();
     850        return;
     851    }
     852    APIRET rc = DosSetMem(bmpBits, dwSize, PAG_COMMIT|PAG_READ|PAG_WRITE);
     853    if(rc) {
     854        //might already be committed
     855        rc = DosSetMem(bmpBits, dwSize, PAG_READ|PAG_WRITE);
     856        if(rc) {
     857            dprintf(("DIBSection::sync: DosSetMem failed with %d!!", rc));
     858            DebugInt3();
     859        }
     860    }
     861    if(hdc == 0) {
     862         HBITMAP hOldBmp;
     863         HDC hdcFlush = CreateCompatibleDC(0);
     864
     865         hOldBmp = SelectObject(hdcFlush, hBitmap);
     866         sync(hdcFlush, 0, pOS2bmp->cy);
     867
     868         SelectObject(hdcFlush, hOldBmp);
     869         DeleteDC(hdcFlush);
     870    }
     871    else sync(hdc, 0, pOS2bmp->cy);
     872   
     873    fInvalid = FALSE;
     874
     875    //Set bitmap memory to readonly again to detect updates
     876    rc = DosSetMem(bmpBits, dwSize, PAG_READ);
     877    if(rc) {
     878        dprintf(("DosSetMem failed with %d!!", rc));
     879        DebugInt3();
     880    }
     881}
     882//******************************************************************************
     883//******************************************************************************
     884void DIBSection::syncAll()
     885{
     886  if (!section)
     887      return;
     888
     889  lock();
     890  DIBSection *dsect = section;
     891
     892  do
     893  {
     894      if(dsect->isDirty() && dsect->isInvalid()) {
     895          DebugInt3();
     896      }
     897      if(dsect->isInvalid())
     898      {
     899          dsect->sync();
     900      }
     901      dsect = dsect->next;
     902  }
     903  while(dsect);
     904
     905  unlock();
     906
     907  return;
    771908}
    772909//******************************************************************************
     
    796933  this->hdc  = hdc;
    797934  hwndParent = WindowFromDC(hdc);
    798   dprintf(("SelectDIBObject %x into %x hwndParent = %x", handle, hdc, hwndParent));
    799 }
    800 //******************************************************************************
    801 //******************************************************************************
    802 DIBSection *DIBSection::findObj(HANDLE handle)
     935  dprintf(("SelectDIBObject %x into %x hwndParent = %x", hBitmap, hdc, hwndParent));
     936}
     937//******************************************************************************
     938//******************************************************************************
     939DIBSection *DIBSection::findObj(HBITMAP hBitmap)
    803940{
    804941  // PH 2001-08-18 shortcut for performance optimization
     
    806943      return NULL;
    807944
     945  lock();
    808946  DIBSection *dsect = section;
    809   lock();
    810947
    811948  do
    812949  {
    813     if(dsect->handle == handle)
     950    if(dsect->hBitmap == hBitmap)
    814951    {
    815952        unlock();
     
    832969      return NULL;
    833970 
     971  lock();
    834972  DIBSection *dsect = section;
    835973 
    836   lock();
    837974  do
    838975  {
     
    851988//******************************************************************************
    852989//******************************************************************************
    853 void DIBSection::deleteSection(HANDLE handle)
    854 {
    855  DIBSection *dsect = findObj(handle);
     990void DIBSection::deleteSection(HBITMAP hBitmap)
     991{
     992 DIBSection *dsect = findObj(hBitmap);
    856993
    857994  if(dsect)
     
    8651002 LPBITMAP_W  dsBm        = (LPBITMAP_W)lpBuffer;
    8661003
    867   dprintf2(("GetDIBSection %x %d %x", handle, iSize, lpBuffer));
     1004  dprintf2(("GetDIBSection %x %d %x", hBitmap, iSize, lpBuffer));
    8681005  if(iSize == sizeof(DIBSECTION))
    8691006  {
     
    9171054DIBSection      *DIBSection::section = NULL;
    9181055CRITICAL_SECTION DIBSection::dibcritsect;
     1056
     1057
     1058//******************************************************************************
     1059//******************************************************************************
     1060static BOOL WIN32API DIBExceptionNotify(LPVOID lpBase, ULONG offset, BOOL fWriteAccess,
     1061                                        DWORD dwSize, DWORD dwUserData)
     1062{
     1063    DIBSection *dsect;
     1064    HBITMAP hBitmap = (HBITMAP)dwUserData;
     1065
     1066    dprintf(("DIBExceptionNotify %x %x %d %d %x", lpBase, offset, fWriteAccess, dwSize, dwUserData));
     1067
     1068    dsect = DIBSection::findObj(hBitmap);
     1069    if(dsect == NULL) {
     1070        dprintf(("dib section not found!!"));
     1071        DebugInt3();
     1072        return FALSE;
     1073    }
     1074    if(dsect->isInvalid())
     1075    {//implies read or write to reserved pages
     1076        //synchronize bitmap memory and bitmap object
     1077        dsect->sync();
     1078    }
     1079    else
     1080    if(!fWriteAccess) {
     1081        APIRET rc = DosSetMem(lpBase, dwSize, PAG_READ|PAG_COMMIT);
     1082        if(rc) {
     1083            dprintf(("DosSetMem failed with %d!!", rc));
     1084            DebugInt3();
     1085            return FALSE;
     1086        }
     1087    }
     1088
     1089    if(fWriteAccess) {
     1090        APIRET rc = DosSetMem(lpBase, dwSize, PAG_READ|PAG_WRITE);
     1091        if(rc) {
     1092            dprintf(("DosSetMem failed with %d!!", rc));
     1093            DebugInt3();
     1094            return FALSE;
     1095        }
     1096        dsect->setDirty();
     1097    }
     1098
     1099
     1100    return TRUE;
     1101}
     1102//******************************************************************************
     1103//******************************************************************************
  • trunk/src/gdi32/dibsect.h

    r10321 r10373  
    1 /* $Id: dibsect.h,v 1.27 2003-11-14 17:31:47 sandervl Exp $ */
     1/* $Id: dibsect.h,v 1.28 2004-01-11 11:42:11 sandervl Exp $ */
    22
    33/*
     
    7575#endif
    7676
     77//
     78//Mark DIB section as invalid (dib section memory is out of sync with
     79//GDI bitmap).
     80//
     81//This must be done for any GDI function that modifies the bitmap
     82//
     83#define DIBSECTION_MARK_INVALID(hdc)                              \
     84    if(DIBSection::getSection() != NULL) {                        \
     85        DIBSection *dib = DIBSection::findHDC(hdc);               \
     86        if(dib) {                                                 \
     87            dib->setInvalid();                                    \
     88        }                                                         \
     89    }
     90
     91#define DIBSECTION_MARK_INVALID_BMP(hBitmap)                      \
     92    if(DIBSection::getSection() != NULL) {                        \
     93        DIBSection *dib = DIBSection::findObj(hBitmap);           \
     94        if(dib) {                                                 \
     95            dib->setInvalid();                                    \
     96        }                                                         \
     97    }
     98
     99//
     100//Check if DIB section is marked dirty (bitmap data modified by application)
     101//If true, then update the GDI bitmap
     102//
     103//This must be done for any GDI function that accesses the bitmap
     104//
     105#define DIBSECTION_CHECK_IF_DIRTY(hdc)                            \
     106    if(DIBSection::getSection() != NULL) {                        \
     107        DIBSection *dib = DIBSection::findHDC(hdc);               \
     108        if(dib && dib->isDirty()) {                               \
     109            dib->flush();                                         \
     110        }                                                         \
     111    }
     112
     113#define DIBSECTION_CHECK_IF_DIRTY_BMP(hBitmap)                    \
     114    if(DIBSection::getSection() != NULL) {                        \
     115        DIBSection *dib = DIBSection::findObj(hBitmap);           \
     116        if(dib && dib->isDirty()) {                               \
     117            dib->flush();                                         \
     118        }                                                         \
     119    }
     120
     121
    77122class DIBSection
    78123{
    79124public:
    80               DIBSection(BITMAPINFOHEADER_W *pbmi, char *pColors, DWORD iUsage, DWORD hSection, DWORD dwOffset, DWORD handle, int fFlip);
     125              DIBSection(BITMAPINFOHEADER_W *pbmi, char *pColors, DWORD iUsage, DWORD hSection, DWORD dwOffset, HBITMAP hBitmap, int fFlip);
    81126             ~DIBSection();
    82127
     
    88133              void  UnSelectDIBObject()      { this->hdc = 0;   };
    89134
    90         DWORD GetBitmapHandle()      { return handle; };
    91               void  SetBitmapHandle(DWORD bmphandle) { handle = bmphandle; };
     135              void  setDirty()               { fDirty = TRUE;   };
     136              BOOL  isDirty()                { return fDirty;   }
     137              void  setInvalid();
     138              BOOL  isInvalid()              { return fInvalid; };
     139
     140        DWORD GetBitmapHandle()              { return hBitmap; };
     141              void  SetBitmapHandle(DWORD bmphandle) { hBitmap = bmphandle; };
    92142        DWORD GetRGBUsage()            { return iUsage; };
    93143
     
    97147                           int nSrcWidth, int nSrcHeight,
    98148                           DWORD Rop);
     149
     150              void  flush();
     151              void  sync();
     152
    99153              void  sync(HDC hdc, DWORD nYdest, DWORD nDestHeight, BOOL orgYInversion = TRUE);
     154              void  flush(HDC hdc, DWORD nYdest, DWORD nDestHeight, BOOL orgYInversion = TRUE);
    100155              void  sync(DWORD xDst, DWORD yDst, DWORD widthDst, DWORD heightDst, PVOID bits);
     156
    101157               int  SetDIBColorTable(int startIdx, int cEntries, RGBQUAD *rgb);
    102158               int  GetDIBColorTable(int startIdx, int cEntries, RGBQUAD *rgb);
    103159               int  SetDIBColorTable(int startIdx, int cEntries, PALETTEENTRY *rgb);
    104160
    105                int  SetDIBits(HDC hdc, HBITMAP hbitmap, UINT startscan, UINT
    106                               lines, const VOID *bits, BITMAPINFOHEADER_W *pbmi,
    107                               UINT coloruse);
    108 
    109161               int  GetDIBSection(int iSize , void *lpBuffer);
    110162
    111163 static DIBSection *getSection() { return section; } ;
    112  static DIBSection *findObj(HANDLE handle);
     164 static DIBSection *findObj(HBITMAP hBitmap);
    113165 static DIBSection *findHDC(HDC hdc);
    114  static       void  deleteSection(HANDLE handle);
     166 static       void  deleteSection(HBITMAP hBitmap);
    115167
    116168 static       void  initDIBSection();
     
    119171 static       void  unlock() { LeaveCriticalSection(&dibcritsect); };
    120172
     173 static       void  syncAll();
     174
    121175protected:
    122176
    123177private:
    124           DWORD handle, iUsage;
    125           DWORD hSection, dwOffset;
     178          HBITMAP hBitmap;
     179 
     180          DWORD hSection, dwOffset, iUsage, dwSize;
    126181          HWND  hwndParent;
    127182          HDC   hdc;
     
    131186    DIBSECTION  dibinfo;
    132187
     188          BOOL  fDirty;         //bitmap is out of sync with dib memory
     189          BOOL  fInvalid;       //dib memory is out of sync with bitmap
     190
    133191    BITMAPINFO2 *pOS2bmp;
    134192                             // Linked list management
     
    139197};
    140198
    141 #define DIBSECTION_MARK_INVALID(a)
    142 #define DIBSECTION_CHECK_IF_DIRTY(a)
    143 
    144199#endif
    145200
  • trunk/src/gdi32/font.cpp

    r10372 r10373  
    1 /* $Id: font.cpp,v 1.34 2004-01-08 11:11:55 sandervl Exp $ */
     1/* $Id: font.cpp,v 1.35 2004-01-11 11:42:11 sandervl Exp $ */
    22
    33/*
     
    77 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
    88 * Copyright 1998 Patrick Haller
     9 * Copyright 2003 Innotek Systemberatung GmbH (stauff@innotek.de)
    910 *
    1011 * TODO: EnumFontsA/W, EnumFontFamiliesExA/W not complete
     
    3233#include <ctype.h>
    3334#include <string.h>
    34 #include "misc.h"
     35#include <dbglog.h>
    3536#include "unicode.h"
    3637#include <heapstring.h>
     
    4041#include <stats.h>
    4142#include "oslibgpi.h"
     43#include "font.h"
     44#include "ft2supp.h"
    4245
    4346#define DBG_LOCALLOG    DBG_font
     
    4548
    4649ODINDEBUGCHANNEL(GDI32-FONT)
    47 
    4850
    4951typedef struct {
     
    9597  /* reserved for system */
    9698  { DEFAULT_CHARSET, 0, FS(0)},
    97   { DEFAULT_CHARSET, 0, FS(0)},
     99  { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
    98100};
    99101
     
    146148                                  LF_FACESIZE);
    147149}
    148 /***********************************************************************
    149  *           FONT_mbtowc
    150  *
    151  * Returns a '\0' terminated Unicode translation of str using the
    152  * charset of the currently selected font in hdc.  If count is -1 then
    153  * str is assumed to be '\0' terminated, otherwise it contains the
    154  * number of bytes to convert.  If plenW is non-NULL, on return it
    155  * will point to the number of WCHARs (excluding the '\0') that have
    156  * been written.  If pCP is non-NULL, on return it will point to the
    157  * codepage used in the conversion (NB, this may be CP_SYMBOL so watch
    158  * out).  The caller should free the returned LPWSTR from the process
    159  * heap itself.
    160  */
    161 LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
    162 {
    163     UINT cp = CP_ACP;
    164     INT lenW, i;
    165     LPWSTR strW;
    166     CHARSETINFO csi;
    167     int charset = GetTextCharset(hdc);
    168 
    169     if( IsDBCSEnv() && ( charset == 0 ))
    170         cp = CP_ACP;
    171     else
    172     /* Hmm, nicely designed api this one! */
    173     if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET))
    174         cp = csi.ciACP;
    175     else {
    176         switch(charset) {
    177     case OEM_CHARSET:
    178         cp = GetOEMCP();
    179         break;
    180     case DEFAULT_CHARSET:
    181         cp = GetACP();
    182         break;
    183 
    184     case VISCII_CHARSET:
    185     case TCVN_CHARSET:
    186     case KOI8_CHARSET:
    187     case ISO3_CHARSET:
    188     case ISO4_CHARSET:
    189       /* FIXME: These have no place here, but because x11drv
    190          enumerates fonts with these (made up) charsets some apps
    191          might use them and then the FIXME below would become
    192          annoying.  Now we could pick the intended codepage for
    193          each of these, but since it's broken anyway we'll just
    194          use CP_ACP and hope it'll go away...
    195       */
    196         cp = CP_ACP;
    197         break;
    198 
    199 
    200     default:
    201         dprintf(("Can't find codepage for charset %d\n", charset));
    202         break;
    203     }
    204     }
    205 
    206     dprintf(("cp == %d\n", cp));
    207 
    208     if(count == -1) count = strlen(str);
    209     if(cp != CP_SYMBOL) {
    210         lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
    211     strW = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
    212     MultiByteToWideChar(cp, 0, str, count, strW, lenW);
    213     } else {
    214         lenW = count;
    215     strW = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
    216     for(i = 0; i < count; i++) strW[i] = (BYTE)str[i];
    217     }
    218     strW[lenW] = '\0';
    219     dprintf(("mapped %s -> %ls\n", str, strW));
    220     if(plenW) *plenW = lenW;
    221     if(pCP) *pCP = cp;
    222     return strW;
    223 }
     150#ifdef DEBUG
     151//******************************************************************************
     152//******************************************************************************
     153void dprintfLogFont(LOGFONTA *lplf)
     154{
     155  dprintf(("GDI32: lfHeight        = %d\n", lplf->lfHeight));
     156  dprintf(("GDI32: lfWidth          = %d\n", lplf->lfWidth));
     157  dprintf(("GDI32: lfEscapement    = %d\n", lplf->lfEscapement));
     158  dprintf(("GDI32: lfOrientation   = %d\n", lplf->lfOrientation));
     159  dprintf(("GDI32: lfWeight        = %d\n", lplf->lfWeight));
     160  dprintf(("GDI32: lfItalic        = %d\n", lplf->lfItalic));
     161  dprintf(("GDI32: lfUnderline     = %d\n", lplf->lfUnderline));
     162  dprintf(("GDI32: lfStrikeOut     = %d\n", lplf->lfStrikeOut));
     163  dprintf(("GDI32: lfCharSet       = %X\n", lplf->lfCharSet));
     164  dprintf(("GDI32: lfOutPrecision  = %X\n", lplf->lfOutPrecision));
     165  dprintf(("GDI32: lfClipPrecision = %X\n", lplf->lfClipPrecision));
     166  dprintf(("GDI32: lfQuality       = %X\n", lplf->lfQuality));
     167  dprintf(("GDI32: lfPitchAndFamily= %X\n", lplf->lfPitchAndFamily));
     168  dprintf(("GDI32: lfFaceName      = %s\n", lplf->lfFaceName));
     169}
     170//******************************************************************************
     171//******************************************************************************
     172void dprintfTextMetrics(TEXTMETRICA *pwtm)
     173{
     174    dprintf(("pwtm->tmHeight %d", pwtm->tmHeight));
     175    dprintf(("pwtm->tmAscent %d", pwtm->tmAscent));
     176    dprintf(("pwtm->tmDescent %d", pwtm->tmDescent));
     177    dprintf(("pwtm->tmInternalLeading %d", pwtm->tmInternalLeading));
     178    dprintf(("pwtm->tmExternalLeading %d", pwtm->tmExternalLeading));
     179    dprintf(("pwtm->tmAveCharWidth %d", pwtm->tmAveCharWidth));
     180    dprintf(("pwtm->tmMaxCharWidth %d", pwtm->tmMaxCharWidth));
     181    dprintf(("pwtm->tmWeight %d", pwtm->tmWeight));
     182    dprintf(("pwtm->tmOverhang %d", pwtm->tmOverhang));
     183    dprintf(("pwtm->tmDigitizedAspectX %d", pwtm->tmDigitizedAspectX));
     184    dprintf(("pwtm->tmDigitizedAspectY %d", pwtm->tmDigitizedAspectY));
     185    dprintf(("pwtm->tmFirstChar %d", pwtm->tmFirstChar));
     186    dprintf(("pwtm->tmLastChar %d", pwtm->tmLastChar));
     187    dprintf(("pwtm->tmDefaultChar %d", pwtm->tmDefaultChar));
     188    dprintf(("pwtm->tmBreakChar %d", pwtm->tmBreakChar));
     189    dprintf(("pwtm->tmItalic %x", pwtm->tmItalic));
     190    dprintf(("pwtm->tmUnderlined %x", pwtm->tmUnderlined));
     191    dprintf(("pwtm->tmStruckOut %x", pwtm->tmStruckOut));
     192    dprintf(("pwtm->tmPitchAndFamily %x", pwtm->tmPitchAndFamily));
     193    dprintf(("pwtm->tmCharSet %x", pwtm->tmCharSet));
     194}
     195#else
     196#define dprintfLogFont(a)
     197#define dprintfTextMetrics(a)
     198#endif
    224199//******************************************************************************
    225200//******************************************************************************
     
    336311  dprintf(("lpszFace = (%x) %s -> %s\n", lplf->lfFaceName, lplf->lfFaceName, afont.lfFaceName));
    337312
    338   dprintf(("GDI32: CreateFontIndirectA\n"));
    339   dprintf(("GDI32: lfHeight        = %d\n", lplf->lfHeight));
    340   dprintf(("GDI32: lfWidth          = %d\n", lplf->lfWidth));
    341   dprintf(("GDI32: lfEscapement    = %d\n", lplf->lfEscapement));
    342   dprintf(("GDI32: lfOrientation   = %d\n", lplf->lfOrientation));
    343   dprintf(("GDI32: lfWeight        = %d\n", lplf->lfWeight));
    344   dprintf(("GDI32: lfItalic        = %d\n", lplf->lfItalic));
    345   dprintf(("GDI32: lfUnderline     = %d\n", lplf->lfUnderline));
    346   dprintf(("GDI32: lfStrikeOut     = %d\n", lplf->lfStrikeOut));
    347   dprintf(("GDI32: lfCharSet       = %X\n", lplf->lfCharSet));
    348   dprintf(("GDI32: lfOutPrecision  = %X\n", lplf->lfOutPrecision));
    349   dprintf(("GDI32: lfClipPrecision = %X\n", lplf->lfClipPrecision));
    350   dprintf(("GDI32: lfQuality       = %X\n", lplf->lfQuality));
    351   dprintf(("GDI32: lfPitchAndFamily= %X\n", lplf->lfPitchAndFamily));
    352   dprintf(("GDI32: lfFaceName      = %s\n", lplf->lfFaceName));
    353 
    354313  if( IsDBCSEnv())
    355314  {
     
    362321  }
    363322
     323  dprintf(("GDI32: CreateFontIndirectA\n"));
     324  dprintfLogFont((LOGFONTA *)lplf);
     325
    364326  hFont = O32_CreateFontIndirect(&afont);
    365327  if(hFont) {
    366328      STATS_CreateFontIndirect(hFont, &afont);
     329      RegisterFont(hFont, (LPSTR)lplf->lfFaceName);
    367330  }
    368331  return(hFont);
     
    387350//******************************************************************************
    388351int  EXPENTRY_O32 EnumFontProcA(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA
    389                                    lpTextM, DWORD arg3, LPARAM arg4)
    390 {
    391  ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
    392  FONTENUMPROCA proc = (FONTENUMPROCA)lpEnumData->userProc;
    393  USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
     352                                lpTextM, DWORD arg3, LPARAM arg4)
     353{
     354  ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
     355  FONTENUMPROCA proc = (FONTENUMPROCA)lpEnumData->userProc;
     356  USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
     357
     358  if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
     359      lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
     360  }
     361
     362  dprintfLogFont(&lpLogFont->elfLogFont);
     363  dprintfTextMetrics((TEXTMETRICA *)lpTextM);
    394364
    395365  int rc = proc(lpLogFont, lpTextM, arg3, lpEnumData->userData);
     
    408378 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
    409379 int rc;
     380
     381  if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
     382      lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
     383  }
     384
     385  dprintfLogFont(&lpLogFont->elfLogFont);
     386  dprintfTextMetrics((TEXTMETRICA *)lpTextM);
    410387
    411388  memcpy(&LogFont, lpLogFont, ((ULONG)&LogFont.elfLogFont.lfFaceName -
     
    448425//******************************************************************************
    449426int  EXPENTRY_O32 EnumFontProcExA(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA
    450                                      lpTextM, DWORD arg3, LPARAM arg4)
     427                                     lpTextM, DWORD FontType, LPARAM arg4)
    451428{
    452429 ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
     
    456433 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
    457434
     435  if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
     436      lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
     437  }
     438
     439  dprintfLogFont(&lpLogFont->elfLogFont);
     440  dprintfTextMetrics((TEXTMETRICA *)lpTextM);
     441
    458442  memcpy(&logFont, lpLogFont, sizeof(ENUMLOGFONTA));
    459443  memset(logFont.elfScript, 0, sizeof(logFont.elfScript));
     
    461445  memset(&textM.ntmFontSig, 0, sizeof(textM.ntmFontSig));
    462446
    463   dprintf(("EnumFontProcExA %s height %d", logFont.elfLogFont.lfFaceName, textM.ntmTm.tmHeight));
    464 
    465   int rc = proc(&logFont, &textM, arg3, lpEnumData->userData);
     447  dprintf(("EnumFontProcExA %s type %x height %d", logFont.elfLogFont.lfFaceName, FontType, textM.ntmTm.tmHeight));
     448
     449  int rc = proc(&logFont, &textM, FontType, lpEnumData->userData);
    466450  SetFS(selTIB);           // switch back to the saved FS selector
    467451  return rc;
     
    471455//******************************************************************************
    472456int EXPENTRY_O32 EnumFontProcExW(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA lpTextM,
    473                                     DWORD arg3, LPARAM arg4)
     457                                    DWORD FontType, LPARAM arg4)
    474458{
    475459 ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
     
    479463 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
    480464 int rc;
     465
     466  if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
     467      lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
     468  }
     469
     470  dprintfLogFont(&lpLogFont->elfLogFont);
     471  dprintfTextMetrics((TEXTMETRICA *)lpTextM);
    481472
    482473  memcpy(&LogFont, lpLogFont, ((ULONG)&LogFont.elfLogFont.lfFaceName - (ULONG)&LogFont));
     
    512503  memset(&textM.ntmFontSig, 0, sizeof(textM.ntmFontSig));
    513504
    514   dprintf(("EnumFontProcExW %s height %d", lpLogFont->elfLogFont.lfFaceName, textM.ntmTm.tmHeight));
    515   rc = proc(&LogFont, &textM, arg3, lpEnumData->userData);
     505  dprintf(("EnumFontProcExW %s type %x height %d charset %d/%d", lpLogFont->elfLogFont.lfFaceName, FontType, textM.ntmTm.tmHeight, lpTextM->tmCharSet, lpLogFont->elfLogFont.lfCharSet));
     506  rc = proc(&LogFont, &textM, FontType, lpEnumData->userData);
    516507  SetFS(selTIB);           // switch back to the saved FS selector
    517508  return rc;
     
    586577//******************************************************************************
    587578INT WIN32API EnumFontFamiliesExA(HDC hdc,
    588                                  LPLOGFONTA arg2,
     579                                 LPLOGFONTA lpLogFont,
    589580                                 FONTENUMPROCEXA arg3,
    590581                                 LPARAM arg4,
     
    594585  int rc;
    595586
    596   dprintf(("GDI32: EnumFontFamiliesExA not complete %s", arg2->lfFaceName));
     587  dprintf(("GDI32: EnumFontFamiliesExA not complete %s", lpLogFont->lfFaceName));
     588  dprintf(("GDI32: EnumFontFamiliesExA font name %s character set %x", lpLogFont->lfFaceName, lpLogFont->lfCharSet));
    597589
    598590  enumData.userProc = (DWORD)arg3;
     
    600592  enumData.dwFlags  = dwFlags;
    601593
    602   rc = O32_EnumFontFamilies(hdc, arg2->lfFaceName, &EnumFontProcExA, (LPARAM)&enumData);
     594  rc = O32_EnumFontFamilies(hdc, lpLogFont->lfFaceName, &EnumFontProcExA, (LPARAM)&enumData);
    603595
    604596  return rc;
     
    607599//******************************************************************************
    608600INT WIN32API EnumFontFamiliesExW(HDC hdc,
    609                                  LPLOGFONTW arg2,
     601                                 LPLOGFONTW lpLogFont,
    610602                                 FONTENUMPROCEXW arg3,
    611603                                 LPARAM arg4,
     
    614606  ENUMUSERDATA enumData;
    615607  int rc;
    616   char *astring = UnicodeToAsciiString((LPWSTR)arg2->lfFaceName);
     608  char *astring = UnicodeToAsciiString((LPWSTR)lpLogFont->lfFaceName);
    617609
    618610  dprintf(("GDI32: EnumFontFamiliesExW not complete %s", astring));
     611  dprintf(("GDI32: EnumFontFamiliesExW font name %s character set %x", astring, lpLogFont->lfCharSet));
    619612
    620613  enumData.userProc = (DWORD)arg3;
     
    627620  return rc;
    628621}
    629 //******************************************************************************
    630 //******************************************************************************
    631 DWORD WIN32API GetFontData(HDC hdc, DWORD dwTable,
    632                            DWORD dwOffset,
    633                            LPVOID lpvBuffer,
    634                            DWORD dbData)
    635 {
    636   dprintf(("GDI32: GetFontData, not implemented (GDI_ERROR)\n"));
    637   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    638 
    639   return(GDI_ERROR);
    640 }
    641 //******************************************************************************
    642 //******************************************************************************
    643 int WIN32API AddFontResourceA(LPCSTR szFont)
    644 {
    645     HINSTANCE hInstance;
    646 
    647     dprintf(("GDI32: AddFontResourceA %s", szFont));
    648     hInstance = LoadLibraryA(szFont);
    649     if(hInstance) {
    650         dprintf(("AddFontResourceA: executable file; NOT IMPLEMENTED"));
    651         FreeLibrary(hInstance);
    652         return 1;
    653     }
    654     return 1;
    655 }
    656 //******************************************************************************
    657 //******************************************************************************
    658 int WIN32API AddFontResourceW(LPCWSTR szFont)
    659 {
    660  char *astring = UnicodeToAsciiString((LPWSTR)szFont);
    661  BOOL  rc;
    662 
    663     dprintf(("GDI32: AddFontResourceW"));
    664     // NOTE: This will not work as is (needs UNICODE support)
    665     rc = AddFontResourceA(astring);
    666     FreeAsciiString(astring);
    667     return rc;
    668 }
    669 //******************************************************************************
    670 //******************************************************************************
    671 BOOL WIN32API RemoveFontResourceA(LPCSTR lpszFont)
    672 {
    673     dprintf(("GDI32: RemoveFontResourceA %s", lpszFont));
    674     return FALSE;
    675 }
    676 //******************************************************************************
    677 //******************************************************************************
    678 BOOL WIN32API RemoveFontResourceW(LPCWSTR szFont)
    679 {
    680  char *astring = UnicodeToAsciiString((LPWSTR)szFont);
    681  BOOL  rc;
    682 
    683     dprintf(("GDI32: RemoveFontResourceW"));
    684     rc = RemoveFontResourceA(astring);
    685     FreeAsciiString(astring);
    686     return(rc);
    687 }
    688 /*****************************************************************************
    689  * Name      : BOOL CreateScalableFontResourceA
    690  * Purpose   : The CreateScalableFontResourceA function creates a font resource
    691  *             file for a scalable font.
    692  * Parameters: DWORD   fdwHidden       flag for read-only embedded font
    693  *             LPCSTR lpszFontRes     address of filename for font resource
    694  *             LPCSTR lpszFontFile    address of filename for scalable font
    695  *             LPCSTR lpszCurrentPath address of path to font file
    696  * Variables :
    697  * Result    : TRUE / FALSE
    698  * Remark    :
    699  * Status    : UNTESTED STUB
    700  *
    701  * Author    : Patrick Haller [Mon, 1998/06/15 08:00]
    702  *****************************************************************************/
    703 
    704 BOOL WIN32API CreateScalableFontResourceA(DWORD fdwHidden,
    705                                           LPCSTR lpszFontRes,
    706                                           LPCSTR lpszFontFile,
    707                                           LPCSTR lpszCurrentPath)
    708 {
    709   dprintf(("GDI32: CreateScalableFontResourceA %x %s %s %s not implemented", fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath));
    710 
    711 //  return OSLibGpiLoadFonts((LPSTR)lpszFontFile);
    712   return FALSE;
    713 }
    714 
    715 
    716 /*****************************************************************************
    717  * Name      : BOOL CreateScalableFontResourceW
    718  * Purpose   : The CreateScalableFontResourceW function creates a font resource
    719  *             file for a scalable font.
    720  * Parameters: DWORD   fdwHidden       flag for read-only embedded font
    721  *             LPCSTR lpszFontRes     address of filename for font resource
    722  *             LPCSTR lpszFontFile    address of filename for scalable font
    723  *             LPCSTR lpszCurrentPath address of path to font file
    724  * Variables :
    725  * Result    : TRUE / FALSE
    726  * Remark    :
    727  * Status    : UNTESTED STUB
    728  *
    729  * Author    : Patrick Haller [Mon, 1998/06/15 08:00]
    730  *****************************************************************************/
    731 
    732 BOOL WIN32API CreateScalableFontResourceW(DWORD fdwHidden,
    733                                           LPCWSTR lpszFontRes,
    734                                           LPCWSTR lpszFontFile,
    735                                           LPCWSTR lpszCurrentPath)
    736 {
    737   LPSTR lpszFontFileA = NULL, lpszFontResA = NULL, lpszCurrentPathA = NULL;
    738 
    739   dprintf(("GDI32: CreateScalableFontResourceW %x %ls %ls %ls not implemented", fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath));
    740 
    741   STACK_strdupWtoA(lpszFontFile, lpszFontFileA);
    742   STACK_strdupWtoA(lpszFontRes, lpszFontResA);
    743   STACK_strdupWtoA(lpszCurrentPath, lpszCurrentPathA);
    744   return CreateScalableFontResourceA(fdwHidden, lpszFontResA, lpszFontFileA, lpszCurrentPathA);
    745 }
    746 
    747622
    748623/*****************************************************************************
     
    819694
    820695    rc = O32_GetTextMetrics(hdc, pwtm);
    821     dprintf(("GDI32: GetTextMetricsA %x %x returned %d", hdc, pwtm, rc));
     696
     697    if(rc == TRUE) {
     698       if(FT2Module.Ft2QueryFontType(hdc, NULL) == FT2_FONTTYPE_TRUETYPE) {
     699           pwtm->tmPitchAndFamily |= TMPF_TRUETYPE;
     700       }
     701    }
     702    dprintfTextMetrics(pwtm);
    822703    return(rc);
    823704}
     
    826707BOOL WIN32API GetTextMetricsW( HDC hdc, LPTEXTMETRICW pwtm)
    827708{
    828  BOOL rc;
    829  TEXTMETRICA atm;
    830 
    831     dprintf(("GDI32: GetTextMetricsW"));
    832 
    833     rc = O32_GetTextMetrics(hdc, &atm);
     709    BOOL rc;
     710    TEXTMETRICA atm;
     711
     712    rc = GetTextMetricsA(hdc, &atm);
    834713    pwtm->tmHeight = atm.tmHeight;
    835714    pwtm->tmAscent = atm.tmAscent;
     
    853732    pwtm->tmCharSet = atm.tmCharSet;
    854733
    855     dprintf(("GDI32: GetTextMetricsW %x %x returned %d", hdc, pwtm, rc));
    856734    return(rc);
    857735}
    858736//******************************************************************************
    859737//******************************************************************************
    860 int WIN32API GetTextFaceA( HDC hdc, int arg2, LPSTR  arg3)
    861 {
    862     dprintf(("GDI32: GetTextFaceA %x %d %x", hdc, arg2, arg3));
    863     return O32_GetTextFace(hdc, arg2, arg3);
    864 }
    865 //******************************************************************************
    866 //******************************************************************************
    867 int WIN32API GetTextFaceW( HDC hdc, int arg2, LPWSTR  arg3)
    868 {
    869  char *astring = NULL;
    870  int   lenA = GetTextFaceA( hdc, 0, NULL );
    871  int   rc;
    872 
    873     dprintf(("GDI32: GetTextFaceW"));
     738int WIN32API GetTextFaceA( HDC hdc, int nCount, LPSTR lpFaceName)
     739{
     740    int ret;
     741
     742    dprintf(("GDI32: GetTextFaceA %x %d %x", hdc, nCount, lpFaceName));
     743    ret = O32_GetTextFace(hdc, nCount, lpFaceName);
     744    if(ret > 0 && lpFaceName) {
     745        dprintf(("GDI32: GetTextFaceA returned %s", lpFaceName));
     746    }
     747    //We should return the length including null terminator (WGSS doesn't)
     748    if(!lpFaceName) ret++;
     749
     750    return ret;
     751}
     752//******************************************************************************
     753//******************************************************************************
     754int WIN32API GetTextFaceW( HDC hdc, int nCount, LPWSTR  lpFaceName)
     755{
     756    char *astring = NULL;
     757    int   lenA = GetTextFaceA( hdc, 0, NULL );
     758    int   rc;
     759
    874760    astring = ( char * )malloc( lenA );
    875     if( astring )
     761    if( astring == NULL ) //@@VP:2003-11-05 was 'if ( astring )'
    876762        return 0;
    877763
     
    880766    if( rc )
    881767    {
    882         if( arg3 )
     768        if( lpFaceName )
    883769        {
    884             AsciiToUnicodeN(astring, arg3, arg2);
    885             rc = lstrlenW( arg3 );
     770            AsciiToUnicodeN(astring, lpFaceName, nCount);
     771            rc = lstrlenW( lpFaceName );
    886772        }
    887773        else
     
    911797    return 0;
    912798}
    913 //******************************************************************************
    914 //******************************************************************************
     799/*****************************************************************************
     800 * Name      : DWORD GetCharacterPlacementA
     801 * Purpose   : The GetCharacterPlacementA function retrieves information about
     802 *             a character string, such as character widths, caret positioning,
     803 *             ordering within the string, and glyph rendering. The type of
     804 *             information returned depends on the dwFlags parameter and is
     805 *             based on the currently selected font in the given display context.
     806 *             The function copies the information to the specified GCP_RESULTSA
     807 *             structure or to one or more arrays specified by the structure.
     808 * Parameters: HDC     hdc        handle to device context
     809 *             LPCSTR lpString   pointer to string
     810 *             int     nCount     number of characters in string
     811 *             int     nMaxExtent maximum extent for displayed string
     812 *             LPGCP_RESULTSA *lpResults  pointer to buffer for placement result
     813 *             DWORD   dwFlags    placement flags
     814 * Variables :
     815 * Result    :
     816 * Remark    :
     817 * Status    : UNTESTED STUB
     818 *
     819 * Author    : Patrick Haller [Mon, 1998/06/15 08:00]
     820 *****************************************************************************/
     821
     822DWORD WIN32API GetCharacterPlacementA(HDC           hdc,
     823                                         LPCSTR       lpString,
     824                                         int           nCount,
     825                                         int           nMaxExtent,
     826                                         GCP_RESULTSA * lpResults,
     827                                         DWORD         dwFlags)
     828{
     829  dprintf(("GDI32: GetCharacterPlacementA(%08xh,%s,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
     830           hdc,
     831           lpString,
     832           nCount,
     833           nMaxExtent,
     834           lpResults,
     835           dwFlags));
     836
     837  return (0);
     838}
     839
     840/*****************************************************************************
     841 * Name      : DWORD GetCharacterPlacementW
     842 * Purpose   : The GetCharacterPlacementW function retrieves information about
     843 *             a character string, such as character widths, caret positioning,
     844 *             ordering within the string, and glyph rendering. The type of
     845 *             information returned depends on the dwFlags parameter and is
     846 *             based on the currently selected font in the given display context.
     847 *             The function copies the information to the specified GCP_RESULTSW
     848 *             structure or to one or more arrays specified by the structure.
     849 * Parameters: HDC     hdc        handle to device context
     850 *             LPCSTR lpString   pointer to string
     851 *             int     nCount     number of characters in string
     852 *             int     nMaxExtent maximum extent for displayed string
     853 *             GCP_RESULTSW *lpResults  pointer to buffer for placement result
     854 *             DWORD   dwFlags    placement flags
     855 * Variables :
     856 * Result    :
     857 * Remark    :
     858 * Status    : Partly working
     859 *
     860 * Author    : Borrowed Rewind Code
     861 *****************************************************************************/
     862
     863DWORD WIN32API GetCharacterPlacementW(HDC           hdc,
     864                                         LPCWSTR       lpString,
     865                                         int           uCount,
     866                                         int           nMaxExtent,
     867                                         GCP_RESULTSW *lpResults,
     868                                         DWORD         dwFlags)
     869{
     870    return FT2Module.Ft2GetCharacterPlacementW(hdc, lpString, uCount, nMaxExtent, lpResults, dwFlags);
     871}
     872
     873
     874/***********************************************************************
     875 *           FONT_mbtowc
     876 *
     877 * Returns a '\0' terminated Unicode translation of str using the
     878 * charset of the currently selected font in hdc.  If count is -1 then
     879 * str is assumed to be '\0' terminated, otherwise it contains the
     880 * number of bytes to convert.  If plenW is non-NULL, on return it
     881 * will point to the number of WCHARs (excluding the '\0') that have
     882 * been written.  If pCP is non-NULL, on return it will point to the
     883 * codepage used in the conversion (NB, this may be CP_SYMBOL so watch
     884 * out).  The caller should free the returned LPWSTR from the process
     885 * heap itself.
     886 */
     887LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
     888{
     889    UINT cp = CP_ACP;
     890    INT lenW, i;
     891    LPWSTR strW;
     892    CHARSETINFO csi;
     893    int charset = GetTextCharset(hdc);
     894
     895    if( IsDBCSEnv() && ( charset == 0 ))
     896        cp = CP_ACP;
     897    else
     898    /* Hmm, nicely designed api this one! */
     899    if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET))
     900        cp = csi.ciACP;
     901    else {
     902        switch(charset) {
     903        case OEM_CHARSET:
     904            cp = GetOEMCP();
     905            break;
     906        case DEFAULT_CHARSET:
     907            cp = GetACP();
     908            break;
     909
     910        case VISCII_CHARSET:
     911        case TCVN_CHARSET:
     912        case KOI8_CHARSET:
     913        case ISO3_CHARSET:
     914        case ISO4_CHARSET:
     915          /* FIXME: These have no place here, but because x11drv
     916             enumerates fonts with these (made up) charsets some apps
     917             might use them and then the FIXME below would become
     918             annoying.  Now we could pick the intended codepage for
     919             each of these, but since it's broken anyway we'll just
     920             use CP_ACP and hope it'll go away...
     921          */
     922            cp = CP_ACP;
     923            break;
     924
     925
     926        default:
     927            dprintf(("Can't find codepage for charset %d\n", charset));
     928            break;
     929        }
     930    }
     931
     932    dprintf(("cp == %d\n", cp));
     933
     934    if(count == -1) count = strlen(str);
     935    if(cp != CP_SYMBOL) {
     936        lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
     937        strW = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
     938        MultiByteToWideChar(cp, 0, str, count, strW, lenW);
     939    } else {
     940        lenW = count;
     941        strW = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
     942        for(i = 0; i < count; i++) strW[i] = (BYTE)str[i];
     943    }
     944    strW[lenW] = '\0';
     945    dprintf(("mapped %s -> %ls\n", str, strW));
     946    if(plenW) *plenW = lenW;
     947    if(pCP) *pCP = cp;
     948    return strW;
     949}
     950
     951/*************************************************************************
     952 * GetGlyphIndicesA [GDI32.@]
     953 */
     954DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
     955                              LPWORD pgi, DWORD flags)
     956{
     957    DWORD ret;
     958    WCHAR *lpstrW;
     959    INT countW;
     960
     961    dprintf(("GDI32: GetGlyphIndicesA (%p, %s, %d, %p, 0x%lx)\n",
     962          hdc, lpstr, count, pgi, flags));
     963
     964    lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
     965    ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
     966    HeapFree(GetProcessHeap(), 0, lpstrW);
     967
     968    return ret;
     969}
     970
     971/*************************************************************************
     972 * GetGlyphIndicesW [GDI32.@]
     973 */
     974DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
     975                              LPWORD pgi, DWORD flags)
     976{
     977    DWORD ret;
     978
     979    dprintf(("GDI32: GetGlyphIndicesW (%ls, %d, %p, 0x%lx)",
     980             lpstr, count, pgi, flags));
     981
     982    if(!hdc) return GDI_ERROR;
     983
     984    ret = FT2Module.Ft2GetGlyphIndices(hdc, lpstr, count , pgi, flags);
     985    if(ret != GDI_ERROR) {
     986        for(int i=0;i<ret;i++) {
     987            dprintf(("GetGlyphIndices: %c (%x)-> %d", lpstr[i], lpstr[i], pgi[i]));
     988        }
     989    }
     990    return ret;
     991}
     992
     993/***********************************************************************
     994 *           GetGlyphOutlineA    (GDI32.@)
     995 */
     996DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
     997                                 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
     998                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
     999{
     1000    LPWSTR p = NULL;
     1001    DWORD ret;
     1002    UINT c;
     1003
     1004    if ((fuFormat & GGO_GLYPH_INDEX) == 0)
     1005    {
     1006        p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
     1007        if (p)
     1008        {
     1009            c = p[0];
     1010        }
     1011        else
     1012        {
     1013            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     1014            return GDI_ERROR;
     1015        }
     1016    }
     1017    else
     1018    {
     1019        c = uChar;
     1020    }
     1021   
     1022    ret = GetGlyphOutlineW (hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2);
     1023   
     1024    if (p != NULL)
     1025    {
     1026        HeapFree (GetProcessHeap(), 0, p);
     1027    }
     1028   
     1029    return ret;
     1030}
     1031
     1032/***********************************************************************
     1033 *           GetGlyphOutlineW    (GDI32.@)
     1034 */
     1035DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
     1036                               LPGLYPHMETRICS lpgm, DWORD cbBuffer,
     1037                               LPVOID lpBuffer, const MAT2 *lpmat2 )
     1038{
     1039    pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
     1040
     1041    dprintf(("GDI32: GetGlyphOutlineW(%p, %04x, %04x, %p, %ld, %p, %p)\n",
     1042              pHps, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 ));
     1043
     1044    if (!hdc || !pHps)
     1045    {
     1046        SetLastError(ERROR_INVALID_PARAMETER);
     1047        return GDI_ERROR;
     1048    }
     1049
     1050    return FT2Module.Ft2GetGlyphOutline(pHps->hps, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2);
     1051}
     1052//******************************************************************************
     1053//******************************************************************************
     1054DWORD WIN32API GetKerningPairsA( HDC hdc, DWORD nNumPairs, LPKERNINGPAIR lpkrnpair)
     1055{
     1056    return O32_GetKerningPairs(hdc, nNumPairs, lpkrnpair);
     1057}
     1058//******************************************************************************
     1059//******************************************************************************
  • trunk/src/gdi32/font.h

    r10349 r10373  
    77BOOL WIN32API IsSystemFont(HFONT hFont);
    88
     9BOOL RegisterFont(HFONT hFont, LPSTR lfFaceName);
     10
    911LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP);
    1012
     13//text.cpp
     14BOOL WIN32API GetStringWidthW(HDC hdc, LPWSTR lpszString, UINT cbString, PINT pWidthArray);
     15
    1116#endif //__FONT_H__
Note: See TracChangeset for help on using the changeset viewer.