⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dib.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 3 页
字号:
	    xsrc.left	= 0;	    xsrc.right	= sdesc.dwWidth;	} else {	    memset(&xsrc,0,sizeof(xsrc));	}    }    /* First check for the validity of source / destination rectangles. This was       verified using a test application + by MSDN.    */    if ((src != NULL) &&	((xsrc.bottom > sdesc.dwHeight) || (xsrc.bottom < 0) ||	 (xsrc.top > sdesc.dwHeight) || (xsrc.top < 0) ||	 (xsrc.left > sdesc.dwWidth) || (xsrc.left < 0) ||	 (xsrc.right > sdesc.dwWidth) || (xsrc.right < 0) ||	 (xsrc.right < xsrc.left) || (xsrc.bottom < xsrc.top))) {        WARN("Application gave us bad source rectangle for Blt.\n");	return DDERR_INVALIDRECT;    }    /* For the Destination rect, it can be out of bounds on the condition that a clipper       is set for the given surface.    */    if ((This->clipper == NULL) &&	((xdst.bottom > ddesc.dwHeight) || (xdst.bottom < 0) ||	 (xdst.top > ddesc.dwHeight) || (xdst.top < 0) ||	 (xdst.left > ddesc.dwWidth) || (xdst.left < 0) ||	 (xdst.right > ddesc.dwWidth) || (xdst.right < 0) ||	 (xdst.right < xdst.left) || (xdst.bottom < xdst.top))) {        WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n");	return DDERR_INVALIDRECT;    }        /* Now handle negative values in the rectangles. Warning: only supported for now       in the 'simple' cases (ie not in any stretching / rotation cases).       First, the case where nothing is to be done.    */    if (((xdst.bottom <= 0) || (xdst.right <= 0) || (xdst.top >= (int) ddesc.dwHeight) || (xdst.left >= (int) ddesc.dwWidth)) ||        ((src != NULL) &&         ((xsrc.bottom <= 0) || (xsrc.right <= 0) || (xsrc.top >= (int) sdesc.dwHeight) || (xsrc.left >= (int) sdesc.dwWidth))))    {        TRACE("Nothing to be done !\n");        goto release;    }    /* The easy case : the source-less blits.... */    if (src == NULL) {        RECT full_rect;        RECT temp_rect; /* No idea if intersect rect can be the same as one of the source rect */	full_rect.left   = 0;	full_rect.top    = 0;	full_rect.right  = ddesc.dwWidth;	full_rect.bottom = ddesc.dwHeight;        IntersectRect(&temp_rect, &full_rect, &xdst);        xdst = temp_rect;    } else {        /* Only handle clipping on the destination rectangle */        int clip_horiz = (xdst.left < 0) || (xdst.right  > (int) ddesc.dwWidth );        int clip_vert  = (xdst.top  < 0) || (xdst.bottom > (int) ddesc.dwHeight);        if (clip_vert || clip_horiz) {            /* Now check if this is a special case or not... */            if ((((xdst.bottom - xdst.top ) != (xsrc.bottom - xsrc.top )) && clip_vert ) ||                (((xdst.right  - xdst.left) != (xsrc.right  - xsrc.left)) && clip_horiz) ||                (dwFlags & DDBLT_DDFX)) {                WARN("Out of screen rectangle in special case. Not handled right now.\n");                goto release;            }            if (clip_horiz) {              if (xdst.left < 0) { xsrc.left -= xdst.left; xdst.left = 0; }              if (xdst.right > ddesc.dwWidth) { xsrc.right -= (xdst.right - (int) ddesc.dwWidth); xdst.right = (int) ddesc.dwWidth; }            }            if (clip_vert) {                if (xdst.top < 0) { xsrc.top -= xdst.top; xdst.top = 0; }                if (xdst.bottom > ddesc.dwHeight) { xsrc.bottom -= (xdst.bottom - (int) ddesc.dwHeight); xdst.bottom = (int) ddesc.dwHeight; }            }            /* And check if after clipping something is still to be done... */            if ((xdst.bottom <= 0) || (xdst.right <= 0) || (xdst.top >= (int) ddesc.dwHeight) || (xdst.left >= (int) ddesc.dwWidth) ||                (xsrc.bottom <= 0) || (xsrc.right <= 0) || (xsrc.top >= (int) sdesc.dwHeight) || (xsrc.left >= (int) sdesc.dwWidth)) {                TRACE("Nothing to be done after clipping !\n");                goto release;            }        }    }    bpp = GET_BPP(ddesc);    srcheight = xsrc.bottom - xsrc.top;    srcwidth = xsrc.right - xsrc.left;    dstheight = xdst.bottom - xdst.top;    dstwidth = xdst.right - xdst.left;    width = (xdst.right - xdst.left) * bpp;    assert(width <= ddesc.u1.lPitch);    dbuf = (BYTE*)ddesc.lpSurface+(xdst.top*ddesc.u1.lPitch)+(xdst.left*bpp);    if (dwFlags & (DDBLT_WAIT|DDBLT_ASYNC))    {	static BOOL displayed = FALSE;	if (!displayed)	{	    FIXME("dwFlags DDBLT_WAIT and/or DDBLT_ASYNC: can't handle right now.\n");	    displayed = TRUE;	}        dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);    }    /* First, all the 'source-less' blits */    if (dwFlags & DDBLT_COLORFILL) {	ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,			     ddesc.u1.lPitch, lpbltfx->u5.dwFillColor);	dwFlags &= ~DDBLT_COLORFILL;    }    if (dwFlags & DDBLT_DEPTHFILL)	FIXME("DDBLT_DEPTHFILL needs to be implemented!\n");    if (dwFlags & DDBLT_ROP) {	/* Catch some degenerate cases here */	switch(lpbltfx->dwROP) {	case BLACKNESS:	    ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.u1.lPitch,0);	    break;	case 0xAA0029: /* No-op */	    break;	case WHITENESS:	    ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.u1.lPitch,~0);	    break;	case SRCCOPY: /* well, we do that below ? */	    break;	default:	    FIXME("Unsupported raster op: %08lx  Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u5.lpDDSPattern);	    goto error;	}	dwFlags &= ~DDBLT_ROP;    }    if (dwFlags & DDBLT_DDROPS) {	FIXME("\tDdraw Raster Ops: %08lx  Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u5.lpDDSPattern);    }    /* Now the 'with source' blits */    if (src) {	LPBYTE sbase;	int sx, xinc, sy, yinc;	if (!dstwidth || !dstheight) /* hmm... stupid program ? */	    goto release;	sbase = (BYTE*)sdesc.lpSurface+(xsrc.top*sdesc.u1.lPitch)+xsrc.left*bpp;	xinc = (srcwidth << 16) / dstwidth;	yinc = (srcheight << 16) / dstheight;	if (!dwFlags) {	    /* No effects, we can cheat here */	    if (dstwidth == srcwidth) {		if (dstheight == srcheight) {		    /* No stretching in either direction. This needs to be as		     * fast as possible */		    sbuf = sbase;                    /* check for overlapping surfaces */                    if (src != iface || xdst.top < xsrc.top ||                        xdst.right <= xsrc.left || xsrc.right <= xdst.left)                    {                        /* no overlap, or dst above src, so copy from top downwards */                        for (y = 0; y < dstheight; y++)                        {                            memcpy(dbuf, sbuf, width);                            sbuf += sdesc.u1.lPitch;                            dbuf += ddesc.u1.lPitch;                        }                    }                    else if (xdst.top > xsrc.top)  /* copy from bottom upwards */                    {                        sbuf += (sdesc.u1.lPitch*dstheight);                        dbuf += (ddesc.u1.lPitch*dstheight);                        for (y = 0; y < dstheight; y++)                        {                            sbuf -= sdesc.u1.lPitch;                            dbuf -= ddesc.u1.lPitch;                            memcpy(dbuf, sbuf, width);                        }                    }                    else /* src and dst overlapping on the same line, use memmove */                    {                        for (y = 0; y < dstheight; y++)                        {                            memmove(dbuf, sbuf, width);                            sbuf += sdesc.u1.lPitch;                            dbuf += ddesc.u1.lPitch;                        }                    }		} else {		    /* Stretching in Y direction only */		    for (y = sy = 0; y < dstheight; y++, sy += yinc) {			sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch;			memcpy(dbuf, sbuf, width);			dbuf += ddesc.u1.lPitch;		    }		}	    } else {		/* Stretching in X direction */		int last_sy = -1;		for (y = sy = 0; y < dstheight; y++, sy += yinc) {		    sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch;		    if ((sy >> 16) == (last_sy >> 16)) {			/* this sourcerow is the same as last sourcerow -			 * copy already stretched row			 */			memcpy(dbuf, dbuf - ddesc.u1.lPitch, width);		    } else {#define STRETCH_ROW(type) { \		    type *s = (type *) sbuf, *d = (type *) dbuf; \		    for (x = sx = 0; x < dstwidth; x++, sx += xinc) \		    d[x] = s[sx >> 16]; \		    break; }		    switch(bpp) {		    case 1: STRETCH_ROW(BYTE)		    case 2: STRETCH_ROW(WORD)		    case 4: STRETCH_ROW(DWORD)		    case 3: {			LPBYTE s,d = dbuf;			for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {			    DWORD pixel;			    s = sbuf+3*(sx>>16);			    pixel = s[0]|(s[1]<<8)|(s[2]<<16);			    d[0] = (pixel    )&0xff;			    d[1] = (pixel>> 8)&0xff;			    d[2] = (pixel>>16)&0xff;			    d+=3;			}			break;		    }		    default:			FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);			ret = DDERR_UNSUPPORTED;			goto error;		    }#undef STRETCH_ROW		    }		    dbuf += ddesc.u1.lPitch;		    last_sy = sy;		}	    }	} else {           LONG dstyinc = ddesc.u1.lPitch, dstxinc = bpp;           DWORD keylow = 0, keyhigh = 0;           if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE)) {	      if (dwFlags & DDBLT_KEYSRC) {		 keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;		 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;	      } else if (dwFlags & DDBLT_KEYDEST){		 keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;		 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;	      } else if (dwFlags & DDBLT_KEYSRCOVERRIDE) {		 keylow  = lpbltfx->ddckSrcColorkey.dwColorSpaceLowValue;		 keyhigh = lpbltfx->ddckSrcColorkey.dwColorSpaceHighValue;	      } else {		 keylow  = lpbltfx->ddckDestColorkey.dwColorSpaceLowValue;		 keyhigh = lpbltfx->ddckDestColorkey.dwColorSpaceHighValue;	      }              dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE);           }           if (dwFlags & DDBLT_DDFX)  {              LPBYTE dTopLeft, dTopRight, dBottomLeft, dBottomRight, tmp;              LONG tmpxy;              dTopLeft     = dbuf;              dTopRight    = dbuf+((dstwidth-1)*bpp);              dBottomLeft  = dTopLeft+((dstheight-1)*ddesc.u1.lPitch);              dBottomRight = dBottomLeft+((dstwidth-1)*bpp);              if (lpbltfx->dwDDFX & DDBLTFX_ARITHSTRETCHY){                 /* I don't think we need to do anything about this flag */                 WARN("dwflags=DDBLT_DDFX nothing done for DDBLTFX_ARITHSTRETCHY\n");              }              if (lpbltfx->dwDDFX & DDBLTFX_MIRRORLEFTRIGHT) {                 tmp          = dTopRight;                 dTopRight    = dTopLeft;                 dTopLeft     = tmp;                 tmp          = dBottomRight;                 dBottomRight = dBottomLeft;                 dBottomLeft  = tmp;                 dstxinc = dstxinc *-1;              }              if (lpbltfx->dwDDFX & DDBLTFX_MIRRORUPDOWN) {                 tmp          = dTopLeft;                 dTopLeft     = dBottomLeft;                 dBottomLeft  = tmp;                 tmp          = dTopRight;                 dTopRight    = dBottomRight;                 dBottomRight = tmp;                 dstyinc = dstyinc *-1;              }              if (lpbltfx->dwDDFX & DDBLTFX_NOTEARING) {                 /* I don't think we need to do anything about this flag */                 WARN("dwflags=DDBLT_DDFX nothing done for DDBLTFX_NOTEARING\n");              }              if (lpbltfx->dwDDFX & DDBLTFX_ROTATE180) {                 tmp          = dBottomRight;                 dBottomRight = dTopLeft;                 dTopLeft     = tmp;                 tmp          = dBottomLeft;                 dBottomLeft  = dTopRight;                 dTopRight    = tmp;                 dstxinc = dstxinc * -1;                 dstyinc = dstyinc * -1;              }              if (lpbltfx->dwDDFX & DDBLTFX_ROTATE270) {                 tmp          = dTopLeft;                 dTopLeft     = dBottomLeft;                 dBottomLeft  = dBottomRight;                 dBottomRight = dTopRight;                 dTopRight    = tmp;                 tmpxy   = dstxinc;                 dstxinc = dstyinc;                 dstyinc = tmpxy;                 dstxinc = dstxinc * -1;              }              if (lpbltfx->dwDDFX & DDBLTFX_ROTATE90) {                 tmp          = dTopLeft;                 dTopLeft     = dTopRight;                 dTopRight    = dBottomRight;                 dBottomRight = dBottomLeft;                 dBottomLeft  = tmp;                 tmpxy   = dstxinc;                 dstxinc = dstyinc;                 dstyinc = tmpxy;                 dstyinc = dstyinc * -1;              }              if (lpbltfx->dwDDFX & DDBLTFX_ZBUFFERBASEDEST) {                 /* I don't think we need to do anything about this flag */                 WARN("dwflags=DDBLT_DDFX nothing done for DDBLTFX_ZBUFFERBASEDEST\n");              }              dbuf = dTopLeft;              dwFlags &= ~(DDBLT_DDFX);           }#define COPY_COLORKEY_FX(type) { \	    type *s = (type *) sbuf, *d = (type *) dbuf, *dx, tmp; \            for (y = sy = 0; y < dstheight; y++, sy += yinc) { \               (LPBYTE)s = sbase + (sy >> 16) * sdesc.u1.lPitch; \               (LPBYTE)dx = d; \	       for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \		  tmp = s[sx >> 16]; \		  if (tmp < keylow || tmp > keyhigh) dx[0] = tmp; \                  (LPBYTE)dx += dstxinc; \	          } \               (LPBYTE)d += dstyinc; \	    } \            break; }	    switch (bpp) {	    case 1: COPY_COLORKEY_FX(BYTE)	    case 2: COPY_COLORKEY_FX(WORD)	    case 4: COPY_COLORKEY_FX(DWORD) 	    case 3: {LPBYTE s,d = dbuf, dx;		for (y = sy = 0; y < dstheight; y++, sy += yinc) {		    sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch;		    dx = d;		    for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {			DWORD pixel;			s = sbuf+3*(sx>>16);			pixel = s[0]|(s[1]<<8)|(s[2]<<16);                        if (pixel < keylow || pixel > keyhigh){		            dx[0] = (pixel    )&0xff;			    dx[1] = (pixel>> 8)&0xff;			    dx[2] = (pixel>>16)&0xff;                        }		        dx+= dstxinc;		    }		    d += dstyinc;                }                break;}	    default:	       FIXME("%s color-keyed blit not implemented for bpp %d!\n",	          (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);		  ret = DDERR_UNSUPPORTED;		  goto error;#undef COPY_COLORKEY_FX            }	}    }error:    if (dwFlags && FIXME_ON(ddraw)) {	FIXME("\tUnsupported flags: ");	DDRAW_dump_DDBLT(dwFlags);    }release:    IDirectDrawSurface7_Unlock(iface,NULL);    if (src) IDirectDrawSurface7_Unlock(src,NULL);    return DD_OK;}/* BltBatch: generic, unimplemented */HRESULT WINAPIDIB_DirectDrawSurface_BltFast(LPDIRECTDRAWSURFACE7 iface, DWORD dstx,			      DWORD dsty, LPDIRECTDRAWSURFACE7 src,			      LPRECT rsrc, DWORD trans){    ICOM_THIS(IDirectDrawSurfaceImpl,iface);    int			bpp, w, h, x, y;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -