win32context.cpp

来自「这是VCF框架的代码」· C++ 代码 · 共 2,636 行 · 第 1/5 页

CPP
2,636
字号
//Win32Context.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*/#include "vcf/GraphicsKit/GraphicsKit.h"#include "vcf/GraphicsKit/GraphicsKitPrivate.h"#include "vcf/FoundationKit/LocalePeer.h"#include "vcf/GraphicsKit/DrawUIState.h"#include "vcf/GraphicsKit/AggCommon.h"#include "thirdparty/common/agg/include/agg_renderer_scanline.h"#include "thirdparty/common/agg/include/agg_span_allocator.h"#include "thirdparty/common/agg/include/agg_span_interpolator_linear.h"#include "thirdparty/common/agg/include/agg_span_image_filter_rgba.h"#include "thirdparty/common/agg/include/agg_scanline_u.h"#include "vcf/GraphicsKit/Win32VisualStylesWrapper.h"using namespace VCF;Win32Context::Win32Context(){	init();}Win32Context::Win32Context( const unsigned long& width, const unsigned long& height ){	init();	HDC desktopDC = ::GetDC( ::GetDesktopWindow() );	dc_ = ::CreateCompatibleDC( desktopDC );	if ( NULL == dc_ ) {		throw RuntimeException( MAKE_ERROR_MSG_2("Unable to create compatible Device Context for win32 context") );	}	memBitmap_ = ::CreateCompatibleBitmap( desktopDC, width, height );	originalBitmap_ = (HBITMAP)::SelectObject( dc_, memBitmap_ );	ReleaseDC( ::GetDesktopWindow(), desktopDC );	isMemoryCtx_ = true;	if ( NULL == memBitmap_ ){		//throw exception		throw RuntimeException( MAKE_ERROR_MSG_2("Unable to create memory bitmap for win32 context") );	}}Win32Context::Win32Context( OSHandleID contextID ){	init();	dc_ = (HDC)contextID;}Win32Context::~Win32Context(){	if ( NULL != clipRGN_ ) {		::DeleteObject( clipRGN_ );	}	if ( NULL != memBitmap_ ){		::SelectObject( dc_, originalBitmap_ );		::DeleteObject( memBitmap_ );	}	if ( true == isMemoryCtx_ ) {		if ( NULL != dc_ ) {			::DeleteDC( dc_ );		}	}	dc_ = NULL;	//clearBuffer();}void Win32Context::init(){	strokeWidth_ = 1.0;	dc_ = NULL;	clipRGN_ = NULL;	context_ = NULL;	memBitmap_ = NULL;	originalBitmap_ = NULL;	pathStarted_ = false;	isMemoryCtx_ = false;	oldOrigin_.x_ = 0.0;	oldOrigin_.y_ = 0.0;	origin_.x_ = 0.0;	origin_.y_ = 0.0;	isXORModeOn_ = false;	alignToBaseline_ = false;	currentDCState_ = 0;	currentHBrush_ = NULL;	currentHPen_ = NULL;	currentHFont_ = NULL;}void Win32Context::releaseHandle(){	//clearBuffer();}class ColorAlpha {public:	ColorAlpha():alphaValue_(255){}	int alphaValue_;	int calculate(int alpha, int c, int, int, int) const {		return alphaValue_;	}};typedef agg::renderer_base<pixfmt> RendererBase;typedef agg::renderer_scanline_aa_solid<RendererBase> SolidRenderer;typedef agg::span_allocator<agg::rgba8> SpanAllocator;typedef agg::span_interpolator_linear<> SpanInterpolator;typedef agg::span_image_filter_rgba_bilinear_clip<pixfmt,SpanInterpolator> SpanGenerator;typedef agg::renderer_scanline_aa_solid<RendererBase> RendererType;void Win32Context::drawGrayScaleImage( const double& x, const double& y, Rect* imageBounds, Image* image ){	Matrix2D& currentXFrm = *context_->getCurrentTransform();	agg::path_storage imagePath;	imagePath.move_to( imageBounds->left_, imageBounds->top_ );	imagePath.line_to( imageBounds->right_, imageBounds->top_ );	imagePath.line_to( imageBounds->right_, imageBounds->bottom_ );	imagePath.line_to( imageBounds->left_, imageBounds->bottom_ );	imagePath.close_polygon();	bool safeToRender = true;	BITMAPINFO bmpInfo;	memset( &bmpInfo, 0, sizeof(BITMAPINFO) );	bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);	bmpInfo.bmiHeader.biPlanes = 1;	bmpInfo.bmiHeader.biBitCount = 32;	bmpInfo.bmiHeader.biCompression = BI_RGB;	int destLeft = 0;	int destTop = 0;	agg::rasterizer_scanline_aa<> rasterizer;	agg::scanline_u8 scanLine;	SysPixelType* bmpBuf = NULL;	HDC memDC = ::CreateCompatibleDC( NULL );	HBITMAP hbmp = NULL;	HBITMAP oldBMP = NULL;	agg::rendering_buffer imgRenderBuf;	Rect xfrmedImageRect = *imageBounds;	bool defaultXFrm = context_->isDefaultTransform();	if ( !defaultXFrm ) {		double xx = x * (currentXFrm[Matrix2D::mei00]) +							y * (currentXFrm[Matrix2D::mei10]) +								(currentXFrm[Matrix2D::mei20]);		double yy = x * (currentXFrm[Matrix2D::mei01]) +							y * (currentXFrm[Matrix2D::mei11]) +								(currentXFrm[Matrix2D::mei21]);		agg::trans_affine pathMat;		pathMat *= agg::trans_affine_rotation( Math::degreesToRadians( context_->getRotation() ) );		pathMat *= agg::trans_affine_scaling( context_->getScaleX(), context_->getScaleY() );		pathMat *= agg::trans_affine_skewing( Math::degreesToRadians(context_->getShearX()),										Math::degreesToRadians(context_->getShearY()) );		agg::conv_transform< agg::path_storage > xfrmedImgPath(imagePath,pathMat);		double vert_x, vert_y;		xfrmedImgPath.vertex( &vert_x, &vert_y );		Point p1(vert_x, vert_y );		xfrmedImgPath.vertex( &vert_x, &vert_y );		Point p2( vert_x, vert_y );		if ( p2.x_ > p1.x_ ) {			xfrmedImageRect.left_ = p1.x_;		}		else {			xfrmedImageRect.left_ = p2.x_;		}		if ( p1.x_ < p2.x_ ) {			xfrmedImageRect.right_ = p2.x_;		}		else {			xfrmedImageRect.right_ = p1.x_;		}		if ( p2.y_ > p1.y_ ) {			xfrmedImageRect.top_ = p1.y_;		}		else {			xfrmedImageRect.top_ = p2.y_;		}		if ( p1.y_ < p2.y_ ) {			xfrmedImageRect.bottom_ = p2.y_;		}		else {			xfrmedImageRect.bottom_ = p1.y_;		}		unsigned cmd = xfrmedImgPath.vertex(&vert_x, &vert_y);		while(!agg::is_stop(cmd)) {			if ( xfrmedImageRect.left_ > vert_x ) {				xfrmedImageRect.left_ = vert_x;			}			if ( xfrmedImageRect.right_ < vert_x ) {				xfrmedImageRect.right_ = vert_x;			}			if ( xfrmedImageRect.top_ > vert_y ) {				xfrmedImageRect.top_ = vert_y;			}			if ( xfrmedImageRect.bottom_ < vert_y ) {				xfrmedImageRect.bottom_ = vert_y;			}			cmd = xfrmedImgPath.vertex(&vert_x, &vert_y);		}		xfrmedImageRect.offset( xx, yy );		xfrmedImageRect.inflate( 2, 2 );		double imageTX = imageBounds->getWidth()/2.0;		double imageTY = imageBounds->getHeight()/2.0;		double xfrmImageTX = xfrmedImageRect.getWidth()/2.0;		double xfrmImageTY = xfrmedImageRect.getHeight()/2.0;		agg::trans_affine pathMat2;		pathMat2 *= agg::trans_affine_translation( -imageTX, -imageTY );		pathMat2 *= agg::trans_affine_rotation( Math::degreesToRadians( context_->getRotation() ) );		pathMat2 *= agg::trans_affine_scaling( context_->getScaleX(), context_->getScaleY() );		pathMat2 *= agg::trans_affine_skewing( Math::degreesToRadians(context_->getShearX()),										Math::degreesToRadians(context_->getShearY()) );		pathMat2 *= agg::trans_affine_translation( xfrmImageTX, xfrmImageTY );		agg::conv_transform< agg::path_storage > xfrmedImgPath2(imagePath,pathMat2);		bmpInfo.bmiHeader.biWidth = (long)xfrmedImageRect.getWidth();		bmpInfo.bmiHeader.biHeight = (long)-xfrmedImageRect.getHeight(); // Win32 DIB are upside down - do this to filp it over		bmpInfo.bmiHeader.biSizeImage = (-bmpInfo.bmiHeader.biHeight) * bmpInfo.bmiHeader.biWidth * 4;		hbmp = CreateDIBSection ( memDC, &bmpInfo, DIB_RGB_COLORS, (void**)&bmpBuf, NULL, NULL );		safeToRender = (NULL != hbmp) ? true : false;		if ( safeToRender ) {			HBITMAP oldBMP = (HBITMAP)SelectObject( memDC, hbmp );			BitBlt( memDC, 0, 0, bmpInfo.bmiHeader.biWidth, -bmpInfo.bmiHeader.biHeight,					dc_, xfrmedImageRect.left_, xfrmedImageRect.top_, SRCCOPY );			imgRenderBuf.attach( (unsigned char*)bmpBuf, bmpInfo.bmiHeader.biWidth,										-bmpInfo.bmiHeader.biHeight,										bmpInfo.bmiHeader.biWidth * 4 );			pixfmt pixf(imgRenderBuf);			RendererBase rb(pixf);			agg::trans_affine imageMat;			imageMat *= agg::trans_affine_translation( -imageTX, -imageTY );			imageMat *= agg::trans_affine_rotation( Math::degreesToRadians( context_->getRotation() ) );			imageMat *= agg::trans_affine_scaling( context_->getScaleX(), context_->getScaleY() );			imageMat *= agg::trans_affine_skewing( Math::degreesToRadians(context_->getShearX()),											Math::degreesToRadians(context_->getShearY()) );			imageMat *= agg::trans_affine_translation( xfrmImageTX, xfrmImageTY );			imageMat.invert();			SpanAllocator spanAllocator;			SpanInterpolator interpolator(imageMat);			agg::rendering_buffer tmpImgRenderBuf;			tmpImgRenderBuf.attach( (unsigned char*)image->getData(),									image->getWidth(),									image->getHeight(),									image->getWidth() * image->getType() );			pixfmt tmpPixf(tmpImgRenderBuf);			SpanGenerator spanGen(//spanAllocator,							 tmpPixf,							 agg::rgba(0, 0, 0, 0.0),							 interpolator);			RendererType imageRenderer(rb);			rasterizer.add_path(xfrmedImgPath2);			agg::render_scanlines_aa(rasterizer, scanLine, rb, spanAllocator, spanGen );		}	}	else {		bmpInfo.bmiHeader.biWidth = (long)xfrmedImageRect.getWidth();		bmpInfo.bmiHeader.biHeight = (long)-xfrmedImageRect.getHeight(); // Win32 DIB are upside down - do this to filp it over		bmpInfo.bmiHeader.biSizeImage = (-bmpInfo.bmiHeader.biHeight) * bmpInfo.bmiHeader.biWidth * 4;		hbmp = CreateDIBSection ( memDC, &bmpInfo, DIB_RGB_COLORS, (void**)&bmpBuf, NULL, NULL );		safeToRender = (NULL != hbmp) ? true : false;		if ( safeToRender ) {			HBITMAP oldBMP = (HBITMAP)SelectObject( memDC, hbmp );			BitBlt( memDC, 0, 0, bmpInfo.bmiHeader.biWidth, -bmpInfo.bmiHeader.biHeight,					dc_, xfrmedImageRect.left_, xfrmedImageRect.top_, SRCCOPY );			imgRenderBuf.attach( (unsigned char*)bmpBuf, bmpInfo.bmiHeader.biWidth,										-bmpInfo.bmiHeader.biHeight,										bmpInfo.bmiHeader.biWidth * 4 );			agg::trans_affine imageMat;			pixfmt pixf(imgRenderBuf);			RendererBase rb(pixf);			SpanAllocator spanAllocator;			SpanInterpolator interpolator(imageMat);			agg::rendering_buffer tmpImgRenderBuf;			tmpImgRenderBuf.attach( (unsigned char*)image->getData(),									image->getWidth(),									image->getHeight(),									image->getWidth() * image->getType() );			pixfmt tmpPixf(tmpImgRenderBuf);			//image->getImageBits()->attachRenderBuffer( image->getWidth(), image->getHeight() );			SpanGenerator spanGen(//spanAllocator,							 tmpPixf,							 agg::rgba(0, 0, 0, 0.0),							 interpolator);			RendererType imageRenderer(rb);			//rasterizer.add_path(imagePath);			//rasterizer.render(scanLine, imageRenderer);		}	}	if ( safeToRender ) {		SetDIBitsToDevice( dc_,								(long)xfrmedImageRect.left_,								(long)xfrmedImageRect.top_,								(long)xfrmedImageRect.getWidth(),								(long)xfrmedImageRect.getHeight(),								0,								0,								0,								(long)xfrmedImageRect.getHeight(),								bmpBuf,								&bmpInfo,								DIB_RGB_COLORS );		SelectObject( memDC, oldBMP );		DeleteObject( hbmp );		DeleteDC( memDC );	}}void Win32Context::drawImage( const double& x, const double& y, Rect* imageBounds, Image* image ){	//checkHandle();	if ( (imageBounds->getWidth() > image->getWidth()) || (imageBounds->getHeight() > image->getHeight()) ) {		throw BasicException( MAKE_ERROR_MSG("Invalid image bounds requested"), __LINE__);	}	if ( image->getType() == Image::itGrayscale ) {		drawGrayScaleImage( x, y, imageBounds, image );		return;	}	//drawImageAGG( x, y, imageBounds, image );	//return;	Matrix2D& currentXFrm = *context_->getCurrentTransform();	if ( !context_->isDefaultTransform() ) {		bool safeToRender = true;		double xx = x * (currentXFrm[Matrix2D::mei00]) +							y * (currentXFrm[Matrix2D::mei10]) +								(currentXFrm[Matrix2D::mei20]);		double yy = x * (currentXFrm[Matrix2D::mei01]) +							y * (currentXFrm[Matrix2D::mei11]) +								(currentXFrm[Matrix2D::mei21]);		agg::trans_affine pathMat;		pathMat *= agg::trans_affine_rotation( Math::degreesToRadians( context_->getRotation() ) );		pathMat *= agg::trans_affine_scaling( context_->getScaleX(), context_->getScaleY() );		pathMat *= agg::trans_affine_skewing( Math::degreesToRadians(context_->getShearX()),										Math::degreesToRadians(context_->getShearY()) );		agg::path_storage imagePath;		imagePath.move_to( imageBounds->left_, imageBounds->top_ );		imagePath.line_to( imageBounds->right_, imageBounds->top_ );		imagePath.line_to( imageBounds->right_, imageBounds->bottom_ );		imagePath.line_to( imageBounds->left_, imageBounds->bottom_ );		imagePath.close_polygon();		agg::conv_transform< agg::path_storage > xfrmedImgPath(imagePath,pathMat);		double vert_x, vert_y;		xfrmedImgPath.vertex( &vert_x, &vert_y );		Rect xfrmedImageRect;		Point p1(vert_x, vert_y);		xfrmedImgPath.vertex( &vert_x, &vert_y );		Point p2(vert_x, vert_y );		if ( p2.x_ > p1.x_ ) {			xfrmedImageRect.left_ = p1.x_;		}		else {			xfrmedImageRect.left_ = p2.x_;		}		if ( p1.x_ < p2.x_ ) {			xfrmedImageRect.right_ = p2.x_;		}		else {			xfrmedImageRect.right_ = p1.x_;		}		if ( p2.y_ > p1.y_ ) {			xfrmedImageRect.top_ = p1.y_;		}		else {			xfrmedImageRect.top_ = p2.y_;		}		if ( p1.y_ < p2.y_ ) {			xfrmedImageRect.bottom_ = p2.y_;		}		else {			xfrmedImageRect.bottom_ = p1.y_;		}		unsigned cmd = xfrmedImgPath.vertex(&vert_x, &vert_y);		while(!agg::is_stop(cmd)) {			if ( xfrmedImageRect.left_ > vert_x ) {				xfrmedImageRect.left_ = vert_x;			}			if ( xfrmedImageRect.right_ < vert_x ) {				xfrmedImageRect.right_ = vert_x;

⌨️ 快捷键说明

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