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 + -
显示快捷键?