SCERROR Surface::BitBlt_( Surface* to, Surface* from, int x, int y, const rect_t* rect) { unsigned surfmt = Surface::GET_PIXFORMAT(from->GetFormat()); fail_if ( surfmt != Surface::GET_PIXFORMAT(to->GetFormat()) ); rect_t r; if ( !PrepareRect(r,to,from,x,y,rect) ) return SCE_OK; const int width = r.right-r.left; if ( width == 0 ) return SCE_OK; SurfLock lfrom(from); reterr_if ( lfrom.PeekError() ); SurfLock lto(to); reterr_if ( lto.PeekError() ); int src_stride,dst_stride; // получаем адреса памяти для пикселей cbyte_t* src = (cbyte_t*)lfrom->GetMemory(src_stride); byte_t* dst = (byte_t*)lto->GetMemory(dst_stride); int depth = 0; switch ( surfmt ) { case Surface::RGBx32: depth = 4; break; case Surface::RGB5x5: depth = 2; break; case Surface::PAL: case Surface::ALPHA: depth = 1; break; default: fail_if ("INVALID SURFACE FORMAT"); } dst+=y*dst_stride+x*depth; // src+=r.top*src_stride+r.left*depth; // поправка на координаты const int count = depth*width; for ( int row = r.top; row < r.bottom;++row,src+=src_stride,dst+=dst_stride) memcpy(dst,src,count); return SCE_OK; }
BOOL CCoolBarCtrl::GetItemRect(CCoolBarItem* pFind, CRect* pRect) const { if ( m_pItems.IsEmpty() ) return FALSE; BOOL bRight = FALSE; CRect rcClient, rcItem; PrepareRect( &rcClient ); rcItem.CopyRect( &rcClient ); for ( POSITION pos = m_pItems.GetHeadPosition() ; pos ; ) { CCoolBarItem* pItem = (CCoolBarItem*)m_pItems.GetNext( pos ); if ( ! pItem->m_bVisible ) continue; if ( pItem->m_nID == ID_RIGHTALIGN && ! bRight ) { int nRight = 0; bRight = TRUE; for ( POSITION pos2 = pos ; pos2 ; ) { CCoolBarItem* pRight = (CCoolBarItem*)m_pItems.GetNext( pos2 ); if ( pRight->m_bVisible ) nRight += pRight->m_nWidth; } if ( rcClient.right - rcItem.left >= nRight ) { rcItem.left = rcClient.right - nRight; } } else { rcItem.right = rcItem.left + pItem->m_nWidth; if ( pItem == pFind ) { *pRect = rcItem; return TRUE; } rcItem.OffsetRect( rcItem.Width(), 0 ); } } return FALSE; }
CCoolBarItem* CCoolBarCtrl::HitTest(const CPoint& point, CRect* pItemRect, BOOL bSeparators) const { if ( m_pItems.IsEmpty() ) return NULL; BOOL bRight = FALSE; CRect rcClient, rcItem; PrepareRect( &rcClient ); rcItem.CopyRect( &rcClient ); for ( POSITION pos = m_pItems.GetHeadPosition() ; pos ; ) { CCoolBarItem* pItem = (CCoolBarItem*)m_pItems.GetNext( pos ); if ( ! pItem->m_bVisible ) continue; if ( pItem->m_nID == ID_RIGHTALIGN && ! bRight ) { int nRight = 0; bRight = TRUE; for ( POSITION pos2 = pos ; pos2 ; ) { CCoolBarItem* pRight = (CCoolBarItem*)m_pItems.GetNext( pos2 ); if ( pRight->m_bVisible ) nRight += pRight->m_nWidth; } if ( rcClient.right - rcItem.left >= nRight ) { rcItem.left = rcClient.right - nRight; } } else { rcItem.right = rcItem.left + pItem->m_nWidth; if ( rcItem.PtInRect( point ) ) { if ( pItemRect ) *pItemRect = rcItem; return ( pItem->m_nID != ID_SEPARATOR || bSeparators ) ? pItem : NULL; } rcItem.OffsetRect( rcItem.Width(), 0 ); } } return NULL; }
SCERROR Surface::TransparentBlt_( Surface* to, Surface* from, u32_t trans, int x, int y , const rect_t* rect) { rect_t r; unsigned surfmt = Surface::GET_PIXFORMAT(from->GetFormat()); fail_if ( surfmt != Surface::GET_PIXFORMAT(to->GetFormat()) ); if ( !PrepareRect(r,to,from,x,y,rect) ) return SCE_OK; const int width = r.right-r.left; if ( width == 0 ) return SCE_OK; SurfLock lfrom(from); reterr_if ( lfrom.PeekError() ); SurfLock lto(to); reterr_if ( lto.PeekError() ); int src_stride,dst_stride; // получаем адреса памяти для пикселей cbyte_t* src = (cbyte_t*)lfrom->GetMemory(src_stride); byte_t* dst = (byte_t*)lto->GetMemory(dst_stride); int depth = 0; switch ( surfmt ) { case Surface::RGBx32: depth = 4; break; case Surface::RGB5x5: depth = 2; break; case Surface::PAL: case Surface::ALPHA: depth = 1; break; default: fail_if ("INVALID SURFACE FORMAT"); } dst+=y*dst_stride+x*depth; // src+=r.top*src_stride+r.left*depth; // поправка на координаты switch ( surfmt ) { case Surface::RGBx32: CopyTransparentRect_T(r.bottom-r.top,src,src_stride,dst,dst_stride,width,u32_t(trans)); break; case Surface::RGB5x5: CopyTransparentRect_T(r.bottom-r.top,src,src_stride,dst,dst_stride,width,u16_t(trans)); break; case Surface::PAL: case Surface::ALPHA: CopyTransparentRect_T(r.bottom-r.top,src,src_stride,dst,dst_stride,width,byte_t(trans)); break; default: fail_if ("INVALID SURFACE FORMAT"); } return SCE_OK; }
SCERROR Surface::AlphaValBlt_( Surface* to, Surface* from, unsigned alpha, int x , int y, const rect_t* rect) { retval_if_fail( (from->GetFormat()&Surface::FORMATBITS) == Surface::RGB5x5 , SCE_BAD_FORMAT ); retval_if_fail( (to->GetFormat()&Surface::FORMATBITS) == Surface::RGB5x5 , SCE_BAD_FORMAT ); retval_if_fail( alpha < 256 , SCE_FAIL ); rect_t r; alpha = (alpha&0x0ff)+1; if ( !PrepareRect(r,to,from,x,y,rect) ) return SCE_OK; #if !defined SRC_DST_MSKIN_MASK u16_t SRC_MSKIN_R_MASK,SRC_MSKIN_G_MASK,SRC_MSKIN_B_MASK; u16_t DST_MSKIN_R_MASK,DST_MSKIN_G_MASK,DST_MSKIN_B_MASK; if ( from->GetFormat()&Surface::SHORTGREEN ) { SRC_MSKIN_R_MASK = MSKIN_R_MASK_555; SRC_MSKIN_G_MASK = MSKIN_G_MASK_555; SRC_MSKIN_B_MASK = MSKIN_B_MASK_555; }else{ SRC_MSKIN_R_MASK = MSKIN_R_MASK_565; SRC_MSKIN_G_MASK = MSKIN_G_MASK_565; SRC_MSKIN_B_MASK = MSKIN_B_MASK_565; } if ( to->GetFormat()&Surface::SHORTGREEN ) { DST_MSKIN_R_MASK = MSKIN_R_MASK_555; DST_MSKIN_G_MASK = MSKIN_G_MASK_555; DST_MSKIN_B_MASK = MSKIN_B_MASK_555; }else{ DST_MSKIN_R_MASK = MSKIN_R_MASK_565; DST_MSKIN_G_MASK = MSKIN_G_MASK_565; DST_MSKIN_B_MASK = MSKIN_B_MASK_565; } #endif SurfLock lfrom(from); reterr_if ( lfrom.PeekError() ); SurfLock lto(to); reterr_if ( lto.PeekError() ); int src_stride,dst_stride; // получаем адреса памяти для пикселей cbyte_t* src = (cbyte_t*)lfrom->GetMemory(src_stride); byte_t* dst = (byte_t*)lto->GetMemory(dst_stride); dst+=y*dst_stride+x*2; // src+=r.top*src_stride+r.left*2; // поправка на координаты const int width = r.right-r.left; // количество точек по горизонтали if ( width == 0 ) return SCE_OK; // копируем прямоугольник по строкам for ( int row = r.top; row < r.bottom; ++row,src+=src_stride,dst+=dst_stride) { for ( int i = 0; i < width; ++i ) { { unsigned color = ((cu16_t*)src)[i]; unsigned dcolor = ((u16_t*)dst)[i]; register signed int reg2 = (signed)(color&SRC_MSKIN_R_MASK); register signed int reg = (signed)(dcolor&DST_MSKIN_R_MASK); register unsigned color2 = ((((reg2-reg)*alpha)>>8)+reg)&DST_MSKIN_R_MASK; reg = (signed)(dcolor&DST_MSKIN_G_MASK); reg2 = (signed)(color&SRC_MSKIN_G_MASK); color2 |= ((((reg2-reg)*alpha)>>8)+reg)&DST_MSKIN_G_MASK; reg = (signed)(dcolor&DST_MSKIN_B_MASK); reg2 = (signed)(color&SRC_MSKIN_B_MASK); color2 |= ((((reg2-reg)*alpha)>>8)+reg)&DST_MSKIN_B_MASK; ((u16_t*)dst)[i] = color2; } } } return SCE_OK; }
SCERROR Surface::AlphaBlt3a_( Surface* to, int x , int y, Surface* back, const rect_t* brect, Surface* from, const rect_t* rect, Surface* alpha) { if ( !alpha ) { if ( MultiLayerSurface* mls = Adaptate<MultiLayerSurface>(from) ) { alpha = mls->GetAlphaSurface(); } } retval_if_fail( alpha != 0 , SCE_INVALIDARG ); retval_if_fail( from != 0 , SCE_INVALIDARG ); retval_if_fail( back != 0 , SCE_INVALIDARG ); retval_if_fail( to != 0 , SCE_INVALIDARG ); retval_if_fail( (from->GetFormat()&Surface::FORMATBITS) == Surface::RGB5x5 , SCE_BAD_FORMAT ); retval_if_fail( (to->GetFormat()&Surface::FORMATBITS) == Surface::RGB5x5 , SCE_BAD_FORMAT ); retval_if_fail( (alpha->GetFormat()&Surface::FORMATBITS) == Surface::ALPHA , SCE_BAD_FORMAT ); retval_if_fail( alpha->GetRect() == from->GetRect() , SCE_FAIL ); rect_t r; rect_t r2 = brect?*brect:back->GetRect(); if ( !PrepareRect(r,to,from,x,y,rect) ) return SCE_OK; retval_if_fail ( r.Width() <= r2.Width() , SCE_INVALIDARG ); #if !defined SRC_DST_MSKIN_MASK u16_t SRC_MSKIN_R_MASK,SRC_MSKIN_G_MASK,SRC_MSKIN_B_MASK; u16_t SRC2_MSKIN_R_MASK,SRC2_MSKIN_G_MASK,SRC2_MSKIN_B_MASK; u16_t DST_MSKIN_R_MASK,DST_MSKIN_G_MASK,DST_MSKIN_B_MASK; if ( from->GetFormat()&Surface::SHORTGREEN ) { SRC_MSKIN_R_MASK = MSKIN_R_MASK_555; SRC_MSKIN_G_MASK = MSKIN_G_MASK_555; SRC_MSKIN_B_MASK = MSKIN_B_MASK_555; }else{ SRC_MSKIN_R_MASK = MSKIN_R_MASK_565; SRC_MSKIN_G_MASK = MSKIN_G_MASK_565; SRC_MSKIN_B_MASK = MSKIN_B_MASK_565; } if ( back->GetFormat()&Surface::SHORTGREEN ) { SRC2_MSKIN_R_MASK = MSKIN_R_MASK_555; SRC2_MSKIN_G_MASK = MSKIN_G_MASK_555; SRC2_MSKIN_B_MASK = MSKIN_B_MASK_555; }else{ SRC2_MSKIN_R_MASK = MSKIN_R_MASK_565; SRC2_MSKIN_G_MASK = MSKIN_G_MASK_565; SRC2_MSKIN_B_MASK = MSKIN_B_MASK_565; } if ( to->GetFormat()&Surface::SHORTGREEN ) { DST_MSKIN_R_MASK = MSKIN_R_MASK_555; DST_MSKIN_G_MASK = MSKIN_G_MASK_555; DST_MSKIN_B_MASK = MSKIN_B_MASK_555; }else{ DST_MSKIN_R_MASK = MSKIN_R_MASK_565; DST_MSKIN_G_MASK = MSKIN_G_MASK_565; DST_MSKIN_B_MASK = MSKIN_B_MASK_565; } #endif SurfLock lfrom(from); reterr_if ( lfrom.PeekError() ); SurfLock lback(back); reterr_if ( lfrom.PeekError() ); SurfLock lalpha(alpha); reterr_if ( lalpha.PeekError() ); SurfLock lto(to); reterr_if ( lto.PeekError() ); int src_stride,dst_stride,alp_stride,sbk_stride; // получаем адреса памяти для пикселей cbyte_t* src = (cbyte_t*)lfrom->GetMemory(src_stride); byte_t* dst = (byte_t*)lto->GetMemory(dst_stride); cbyte_t* sbk = (cbyte_t*)lback->GetMemory(sbk_stride); cbyte_t* alp = (cbyte_t*)lalpha->GetMemory(alp_stride); dst+=y*dst_stride+x*2; // src+=r.top*src_stride+r.left*2; // поправка на координаты sbk+=r2.top*sbk_stride+r2.left*2; // поправка на координаты alp+=r.top*alp_stride+r.left; // const int width = r.Width(); // количество точек по горизонтали if ( width == 0 ) return SCE_OK; // копируем прямоугольник по строкам for ( int row = r.top; row < r.bottom; ++row,src+=src_stride,dst+=dst_stride,alp+=alp_stride,sbk+=sbk_stride) { for ( int i = 0; i < width; ++i ) { unsigned int a = alp[i]; if ( a == 255 ) { int j = i+1; for (; j < width && alp[j] == 255; ++j ) ; FastCopy16((u16_t*)dst+i,(cu16_t*)src+i,j-i); i=j-1; } else if ( a == 0 ) { int j = i+1; for (; j < width && alp[j] == 0; ++j ) ; FastCopy16((u16_t*)dst+i,(cu16_t*)sbk+i,j-i); i=j-1; } else { unsigned color = ((cu16_t*)src)[i]; ++a; unsigned dcolor = ((u16_t*)sbk)[i]; register signed int reg2 = (signed)(color&SRC_MSKIN_R_MASK); register signed int reg = (signed)(dcolor&SRC2_MSKIN_R_MASK); register unsigned color2 = ((((reg2-reg)*a)>>8)+reg)&DST_MSKIN_R_MASK; reg = (signed)(dcolor&SRC2_MSKIN_G_MASK); reg2 = (signed)(color&SRC_MSKIN_G_MASK); color2 |= ((((reg2-reg)*a)>>8)+reg)&DST_MSKIN_G_MASK; reg = (signed)(dcolor&SRC2_MSKIN_B_MASK); reg2 = (signed)(color&SRC_MSKIN_B_MASK); color2 |= ((((reg2-reg)*a)>>8)+reg)&DST_MSKIN_B_MASK; ((u16_t*)dst)[i] = color2; } } } return SCE_OK; }