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

📄 dx_viewport.cpp

📁 彩信浏览器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		return;	} else if(is_empty_region(hrgn)) {		// nothing to paint		viewport_logger->trace("%s: Region is empty for transition", 			tr->get_type_str().c_str());		DeleteObject((HGDIOBJ)hrgn);		return;	}		IDirectDrawSurface* surf = create_surface();	if(!tr->is_outtrans()) copy_bgd_to(surf, dst_rc);	draw(src, src_rc, dst_rc, keysrc, surf);	OffsetRgn(hrgn, dst_rc.left(), dst_rc.top());	draw_to_bgd(surf, dst_rc, hrgn);	release_surface(surf);	DeleteObject((HGDIOBJ)hrgn);}void gui::dx::viewport::draw(IDirectDrawSurface* src, const lib::rect& src_rc,	const lib::rect& dst_rc, bool keysrc, IDirectDrawSurface* dstview) {	if(!dstview || !src) return;		RECT srcRC = {src_rc.left(), src_rc.top(), src_rc.right(), src_rc.bottom()};	RECT dstRC = {dst_rc.left(), dst_rc.top(), dst_rc.right(), dst_rc.bottom()};		// Verify:	// 1. Src within surf	RECT surfRC;	set_rect(src, &surfRC);	if(!IntersectRect(&srcRC, &srcRC, &surfRC) || IsRectEmpty(&srcRC))		return;			// 2. Dest within viewport	RECT vrc = {0, 0, m_width, m_height};	if(!IntersectRect(&dstRC, &dstRC, &vrc) || IsRectEmpty(&dstRC))		return;		DWORD flags = DDBLT_WAIT;	if(keysrc) flags |= DDBLT_KEYSRC;	HRESULT hr = dstview->Blt(&dstRC, src, &srcRC, flags, NULL);	if (FAILED(hr)) {		seterror(":viewport::clear/DirectDrawSurface::Blt()", hr);		viewport_logger->trace("Blt %s --> %s failed", repr(src_rc).c_str(), repr(dst_rc).c_str());	}}// Paints the provided stringvoid gui::dx::viewport::draw(const std::basic_string<text_char>& text, const lib::rect& rc, lib::color_t clr) {	if(!m_surface || text.empty()) return;		HDC hdc;	HRESULT hr = m_surface->GetDC(&hdc);	if (FAILED(hr)) {		seterror("DirectDrawSurface::GetDC()", hr);		return;	}	SetBkMode(hdc, TRANSPARENT);	COLORREF crTextColor = (clr == CLR_INVALID)?::GetSysColor(COLOR_WINDOWTEXT):clr;	::SetTextColor(hdc, crTextColor);		RECT dstRC = {rc.left(), rc.top(), rc.right(), rc.bottom()};	UINT uFormat = DT_CENTER | DT_WORDBREAK;	int res = ::DrawText(hdc, text.c_str(), int(text.length()), &dstRC, uFormat); 	if(res == 0)		win_report_last_error("DrawText()");	m_surface->ReleaseDC(hdc);}// Frames the provided rectvoid gui::dx::viewport::frame_rect(const lib::rect& rc, lib::color_t clr) {	if(!m_surface) return;		HDC hdc;	HRESULT hr = m_surface->GetDC(&hdc);	if (FAILED(hr)) {		seterror("DirectDrawSurface::GetDC()", hr);		return;	}	RECT RC = {rc.left(), rc.top(), rc.right(), rc.bottom()};	HBRUSH hbr = CreateSolidBrush(clr);	if(FrameRect(hdc, &RC, hbr) == 0)		win_report_last_error("FrameRect()");	DeleteObject((HGDIOBJ) hbr);	m_surface->ReleaseDC(hdc);}// Helper, that returns the size of a DD surface // staticlib::size gui::dx::viewport::get_size(IDirectDrawSurface* p) {	assert(p);	DDSURFACEDESC desc;	ZeroMemory(&desc, sizeof(desc));	desc.dwSize = sizeof(desc);	desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;	HRESULT hr = p->GetSurfaceDesc(&desc);	assert(SUCCEEDED(hr));	return lib::size(desc.dwWidth, desc.dwHeight);}// Draw the src_rc of the DD surface to the back buffer and destination rectanglevoid gui::dx::viewport::blit(IDirectDrawSurface* src, const lib::rect& src_rc,	IDirectDrawSurface* dst, const lib::rect& dst_rc) {		RECT srcRC = {src_rc.left(), src_rc.top(), src_rc.right(), src_rc.bottom()};	RECT dstRC = {dst_rc.left(), dst_rc.top(), dst_rc.right(), dst_rc.bottom()};		// Verify:	// 1. Src within surf	RECT srcSurfRC;	set_rect(src, &srcSurfRC);	if(!IntersectRect(&srcRC, &srcRC, &srcSurfRC) || IsRectEmpty(&srcRC))		return;			// 2. Dst within surf	RECT dstSurfRC;	set_rect(dst, &dstSurfRC);	if(!IntersectRect(&dstRC, &dstRC, &dstSurfRC) || IsRectEmpty(&dstRC))		return;				DWORD flags = DDBLT_WAIT;	HRESULT hr = dst->Blt(&dstRC, src, &srcRC, flags, NULL);	if (FAILED(hr)) {		seterror("viewport::blit/DirectDrawSurface::Blt()", hr);		viewport_logger->trace("Blt %s --> %s failed", repr(src_rc).c_str(), repr(dst_rc).c_str());	}}// Copies to the DD surface the back buffer within the from rectvoid gui::dx::viewport::rdraw(IDirectDrawSurface* dst, const lib::rect& from_rc) {	if(!m_surface || !dst) return;	DWORD flags = DDBLT_WAIT;		// Set srcRC to surf rect	RECT surfRC;	set_rect(dst, &surfRC);		RECT fromRC = {from_rc.left(), from_rc.top(), from_rc.right(), from_rc.bottom()};		// Verify:	// Dest within viewport	RECT vrc = {0, 0, m_width, m_height};	if(!IntersectRect(&fromRC, &fromRC, &vrc) || IsRectEmpty(&fromRC))		return;		HRESULT hr = dst->Blt(&surfRC, m_surface, &fromRC, flags, NULL);	if (FAILED(hr)) {		seterror("viewport::rdraw/DirectDrawSurface::Blt()", hr);	}}void gui::dx::viewport::copy_bgd_to(IDirectDrawSurface* surf, const lib::rect& rc) { 	if(!m_surface || !surf) return;	DWORD flags = DDBLT_WAIT;	RECT RC = {rc.left(), rc.top(), rc.right(), rc.bottom()};	RECT vrc = {0, 0, m_width, m_height};	if(!IntersectRect(&RC, &RC, &vrc) || IsRectEmpty(&RC)) return;	HRESULT hr = surf->Blt(&RC, m_surface, &RC, flags, NULL);	if (FAILED(hr)) {		seterror("viewport::copy/DirectDrawSurface::Blt()", hr);	}}void gui::dx::viewport::draw_to_bgd(IDirectDrawSurface* surf, const lib::rect& rc, HRGN hrgn) {	if(!m_surface) return;	DWORD flags = DDBLT_WAIT;	RECT RC = {rc.left(), rc.top(), rc.right(), rc.bottom()};	RECT vrc = {0, 0, m_width, m_height};	if(!IntersectRect(&RC, &RC, &vrc) || IsRectEmpty(&RC)) return;		HDC hdc;	HRESULT hr = m_surface->GetDC(&hdc);	if (FAILED(hr)) {		seterror("DirectDrawSurface::GetDC()", hr);		return;	}	HDC hsurfdc;	hr = surf->GetDC(&hsurfdc);	if(FAILED(hr)) {		m_surface->ReleaseDC(hdc);		seterror("DirectDrawSurface::GetDC()", hr);		return;	}		if(hrgn)		SelectClipRgn(hdc, hrgn);		int w = RC.right - RC.left;	int h = RC.bottom - RC.top;	BOOL res = BitBlt(hdc, RC.left, RC.top, w, h, hsurfdc, RC.left, RC.top, SRCCOPY);	if(!res) win_report_last_error("BitBlt");		m_surface->ReleaseDC(hdc);	surf->ReleaseDC(hsurfdc);}////////////////////////// Internal pixel format related functionsuint16 gui::dx::viewport::low_bit_pos(uint32 dword) {	uint32 test = 1;	for(uint16 i=0;i<32;i++){		if(dword & test)			return i;		test <<= 1;	}	return 0;}	uint16 gui::dx::viewport::high_bit_pos(uint32 dword) {	uint32 test = 1;	test <<= 31;	for(uint16 i=0;i<32;i++){		if ( dword & test )			return (uint16)(31-i);		test >>= 1;	}	return 0;}	void gui::dx::viewport::get_pixel_format() {	if(!m_primary_surface) return;		DDPIXELFORMAT format;	memset(&format, 0, sizeof(format));	format.dwSize = sizeof(format);	HRESULT hr = m_primary_surface->GetPixelFormat(&format);	if (FAILED(hr)){		seterror("DirectDrawSurface::GetPixelFormat()", hr);		return;	}		bits_size = format.dwRGBBitCount;	//viewport_logger->trace("bits_size: %u", bits_size);	lo_red_bit = low_bit_pos( format.dwRBitMask );	uint16 hi_red_bit = high_bit_pos( format.dwRBitMask );	red_bits = (uint16)(hi_red_bit-lo_red_bit+1);	lo_green_bit = low_bit_pos( format.dwGBitMask );	uint16 hi_green_bit = high_bit_pos(format.dwGBitMask);	green_bits=(uint16)(hi_green_bit-lo_green_bit+1);	lo_blue_bit  = low_bit_pos( format.dwBBitMask );	uint16 hi_blue_bit  = high_bit_pos(format.dwBBitMask);	blue_bits=(uint16)(hi_blue_bit-lo_blue_bit+1);}// Converts a lib::color_t to a DD coloruint32 gui::dx::viewport::convert(lib::color_t color) {	return convert(lib::redc(color), lib::greenc(color), lib::bluec(color));}// Converts the RGB tuple to a DD coloruint32 gui::dx::viewport::convert(BYTE r, BYTE g, BYTE b) {	uint32 ddcolor = 0;	if(bits_size == 8){		// find from palette		return 0;	} else if(bits_size == 16) {		int rs = 8 - red_bits;		int gs = 8 - green_bits;		int bs = 8 - blue_bits;		ddcolor = ((r >> rs) << lo_red_bit) | ((g>>gs) << lo_green_bit) | ((b>>bs) << lo_blue_bit);	} else if (bits_size==24 || bits_size==32){		ddcolor = (r << lo_red_bit) | (g << lo_green_bit) | (b << lo_blue_bit);			}	return ddcolor;}// Internal function// Converts the provided rect to OS screen coordinatesRECT* gui::dx::viewport::to_screen_rc_ptr(RECT& r) {	POINT pt = {r.left, r.top};	int w = r.right - r.left;	int h = r.bottom - r.top;	ClientToScreen(m_hwnd, &pt);	r.left = pt.x;	r.top = pt.y;	r.right = pt.x + w;	r.bottom = pt.y + h;	return &r;}__forceinline int blend(int w, int c1, int c2) {return (c1==c2)?c1:(c1 + w*(c2-c1)/256); }HRESULT gui::dx::viewport::blt_blend32(const lib::rect& rc, double progress,	IDirectDrawSurface *surf1, IDirectDrawSurface *surf2) {		DDSURFACEDESC desc1, desc2;	ZeroMemory(&desc1, sizeof(desc1));	desc1.dwSize = sizeof(desc1);	ZeroMemory(&desc2, sizeof(desc2));	desc2.dwSize = sizeof(desc2);		HRESULT hr = surf1->Lock(0, &desc1, DDLOCK_WAIT | DDLOCK_READONLY, 0);	if(hr!=DD_OK) return hr;		hr = surf2->Lock(0, &desc2, DDLOCK_WAIT, 0);	if(hr != DD_OK) {			surf1->Unlock(0);		return hr;	}		lib::rect rcv(lib::point(0,0), lib::size(m_width,m_height));	lib::rect rcc = rc;	rcc &= rcv;	int begin_row = rcc.bottom();	int end_row = rcc.top();	int begin_col = rcc.left();	int end_col = rcc.right();		int weight = int(progress*256);		for(int row = begin_row-1;row>=end_row;row--) {		RGBQUAD* px1 = (RGBQUAD*)((BYTE*)desc1.lpSurface+row*desc1.lPitch);		RGBQUAD* px2 = (RGBQUAD*)((BYTE*)desc2.lpSurface+row*desc2.lPitch);		px1 +=  begin_col;		px2 +=  begin_col;		for(int col=begin_col;col<end_col;col++, px1++, px2++) {			px2->rgbRed = (BYTE)blend(weight, px2->rgbRed, px1->rgbRed);			px2->rgbGreen = (BYTE)blend(weight, px2->rgbGreen, px1->rgbGreen);			px2->rgbBlue = (BYTE)blend(weight, px2->rgbBlue, px1->rgbBlue);		}	}	surf1->Unlock(0);	surf2->Unlock(0);	return hr;}HRESULT gui::dx::viewport::blt_blend24(const lib::rect& rc, double progress,	IDirectDrawSurface *surf1, IDirectDrawSurface *surf2) {		DDSURFACEDESC desc1, desc2;	ZeroMemory(&desc1, sizeof(desc1));	desc1.dwSize = sizeof(desc1);	ZeroMemory(&desc2, sizeof(desc2));	desc2.dwSize = sizeof(desc2);		HRESULT hr = surf1->Lock(0, &desc1, DDLOCK_WAIT | DDLOCK_READONLY, 0);	if(hr!=DD_OK) return hr;		hr = surf2->Lock(0, &desc2, DDLOCK_WAIT, 0);	if(hr != DD_OK) {			surf1->Unlock(0);		return hr;	}		lib::rect rcv(lib::point(0,0), lib::size(m_width,m_height));	lib::rect rcc = rc;	rcc &= rcv;	int begin_row = rcc.bottom();	int end_row = rcc.top();	int begin_col = rcc.left();	int end_col = rcc.right();		int weight = int(progress*256);		for(int row = begin_row-1;row>=end_row;row--) {		RGBTRIPLE* px1 = (RGBTRIPLE*)((BYTE*)desc1.lpSurface+row*desc1.lPitch);		RGBTRIPLE* px2 = (RGBTRIPLE*)((BYTE*)desc2.lpSurface+row*desc2.lPitch);		px1 +=  begin_col;		px2 +=  begin_col;		for(int col=begin_col;col<end_col;col++, px1++, px2++) {			px2->rgbtRed = (BYTE)blend(weight, px2->rgbtRed, px1->rgbtRed);			px2->rgbtGreen = (BYTE)blend(weight, px2->rgbtGreen, px1->rgbtGreen);			px2->rgbtBlue = (BYTE)blend(weight, px2->rgbtBlue, px1->rgbtBlue);		}	}	surf1->Unlock(0);	surf2->Unlock(0);	return hr;}struct trible565 {	uint16 v;	trible565() : v(0) {}	trible565(int _r, int _g, int _b)  {		lib::color_t rgb = (_b << 16) | (_g << 8) | _r ;        v = (uint16)((rgb & 0xf80000)>> 8);         v |= (uint16)(rgb & 0xfc00) >> 5;         v |= (uint16)(rgb & 0xf8) >> 3;  	}	trible565(uchar _r, uchar _g, uchar _b) {		lib::color_t rgb = (_b << 16) | (_g << 8) | _r ;        v = (uint16)((rgb & 0xf80000)>> 8); // red        v |= (uint16)(rgb & 0xfc00) >> 5; // green        v |= (uint16)(rgb & 0xf8) >> 3; // blue 	}		trible565(lib::color_t rgb) {        v = (uint16)((rgb & 0xf80000) >> 8);         v |= (uint16)(rgb & 0xfc00) >> 5;         v |= (uint16)(rgb & 0xf8) >> 3;  	}		BYTE blue() { return (v & 0xf800) >> 8;}	BYTE green() { return (v & 0x7e0) >> 2;}	BYTE red() { return (v & 0x1f) << 3;}};HRESULT gui::dx::viewport::blt_blend16(const lib::rect& rc, double progress,	IDirectDrawSurface *surf1, IDirectDrawSurface *surf2) {		DDSURFACEDESC desc1, desc2;	ZeroMemory(&desc1, sizeof(desc1));	desc1.dwSize = sizeof(desc1);	ZeroMemory(&desc2, sizeof(desc2));	desc2.dwSize = sizeof(desc2);		HRESULT hr = surf1->Lock(0, &desc1, DDLOCK_WAIT | DDLOCK_READONLY, 0);	if(hr!=DD_OK) return hr;		hr = surf2->Lock(0, &desc2, DDLOCK_WAIT, 0);	if(hr != DD_OK) {			surf1->Unlock(0);		return hr;	}		lib::rect rcv(lib::point(0,0), lib::size(m_width,m_height));	lib::rect rcc = rc;	rcc &= rcv;	int begin_row = rcc.bottom();	int end_row = rcc.top();	int begin_col = rcc.left();	int end_col = rcc.right();		int weight = int(progress*256);		for(int row = begin_row-1;row>=end_row;row--) {		trible565* px1 = (trible565*)((BYTE*)desc1.lpSurface+row*desc1.lPitch);		trible565* px2 = (trible565*)((BYTE*)desc2.lpSurface+row*desc2.lPitch);		px1 +=  begin_col;		px2 +=  begin_col;		for(int col=begin_col;col<end_col;col++, px1++, px2++) {			BYTE r  = (BYTE)blend(weight, px2->red(), px1->red());			BYTE g = (BYTE)blend(weight, px2->green(), px1->green());			BYTE b = (BYTE)blend(weight, px2->blue(), px1->blue());			*px2 = trible565(r, g, b);		}	}	surf1->Unlock(0);	surf2->Unlock(0);	return hr;}

⌨️ 快捷键说明

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