Графика для Windows средствами DirectDraw | страница 61



> if (destsurf==0 || srcsurf==0) return FALSE;

> BOOL use_fastblt=TRUE;

> DDSURFACEDESC destsurfdesc;

> ZeroMemory(&destsurfdesc, sizeof(destsurfdesc));

> destsurfdesc.dwSize = sizeof(destsurfdesc);

> destsurf->GetSurfaceDesc(&destsurfdesc);

> CRect destrect;

> destrect.left=0;

> destrect.top=0;

> destrect.right=destsurfdesc.dwWidth;

> destrect.bottom=destsurfdesc.dwHeight;

> DDSURFACEDESC srcsurfdesc;

> ZeroMemory(&srcsurfdesc, sizeof(srcsurfdesc));

> srcsurfdesc.dwSize = sizeof(srcsurfdesc);

> srcsurf->GetSurfaceDesc(&srcsurfdesc);

> CRect srcrect;

> srcrect.left=0;

> srcrect.top=0;

> srcrect.right=srcsurfdesc.dwWidth;

> srcrect.bottom=srcsurfdesc.dwHeight;

> // Проверить, нужно ли что-нибудь делать...

> if (x+srcrect.left>=destrect.right) return FALSE;

> if (y+srcrect.top>=destrect.bottom) return FALSE;

> if (x+srcrect.right<=destrect.left) return FALSE;

> if (y+srcrect.bottom<=destrect.top) return FALSE;

> // При необходимости выполнить отсечение

> // для прямоугольной области источника

> if (x+srcrect.right>destrect.right) srcrect.right-=x+srcrect.right-destrect.right;

> if (y+srcrect.bottom>destrect.bottom) srcrect.bottom-=y+srcrect.bottom-destrect.bottom;

> CRect dr;

> if (x<0) {

>  srcrect.left=-x;

>  x=0;

>  dr.left=x;

>  dr.top=y;

>  dr.right=x+srcrect.Width();

>  dr.bottom=y+srcrect.Height();

>  use_fastblt=FALSE;

> }

> if (y<0) {

>  srcrect.top=-y;

>  y=0;

>  dr.left=x;

>  dr.top=y;

>  dr.right=x+srcrect.Width();

>  dr.bottom=y+srcrect.Height();

>  use_fastblt=FALSE;

> }

> DWORD flags;

> if (use_fastblt) {

>  flags=DDBLTFAST_WAIT;

>  if (srccolorkey) flags |= DDBLTFAST_SRCCOLORKEY;

>  destsurf->BltFast(x, y, srcsurf, &srcrect, flags);

> } else {

>  flags=DDBLT_WAIT;

>  if (srccolorkey) flags |= DDBLT_KEYSRC;

>  destsurf->Blt(&dr, srcsurf, &srcrect, flags, 0);

> }

> return TRUE;

>}

Сначала функция BltSurface() проверяет указатели на поверхности. Если хотя бы один из них равен нулю, функция возвращает FALSE, тем самым сообщая о неудаче. Если проверка прошла успешно, два объекта CRect инициализируются в соответствии с размерами поверхностей, полученными с помощью функции DirectDrawSurface::GetSurfaceDesc().

Затем BltSurface() проверяет, что попадает ли точка назначения в границы приемника. Если координаты x и y таковы, что копия не пересекается с поверхностью приемника, блиттинг не нужен, поэтому мы просто выходим из функции.

Если же с точкой назначения все в порядке, функция проверяет, нужно ли выполнять отсечение. Если отсечение не требуется, блит-операция для достижения максимального быстродействия выполняется функцией