x11context.cpp

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

CPP
1,642
字号
//X11Context.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/GraphicsKit/MgcBezierCurve2.h"using namespace VCF;X11Context::X11Context():	X11Display_(NULL),	x11GC_(0),	x11Drawable_(0),	pixmapHeight_(0),	pixmapWidth_(0),	parentImage_(NULL),	memoryImage_(0),	memoryImageAlpha_(0){	init();}X11Context::X11Context( const unsigned long& width, const unsigned long& height ):	X11Display_(NULL),	x11GC_(0),	x11Drawable_(0),	pixmapHeight_(height),	pixmapWidth_(width),	parentImage_(NULL),	memoryImage_(0),	memoryImageAlpha_(0){	//create a pixmap here	//x11Drawable_	X11GraphicsToolkit* toolkit = (X11GraphicsToolkit*)GraphicsToolkit::getDefaultGraphicsToolkit();	X11Display_ = toolkit->getX11Display();	int x11screen = toolkit->getX11ScreenID();	memoryImage_ = imlib_create_image( pixmapWidth_, pixmapHeight_ );	imlib_context_set_image( memoryImage_ );	imlib_context_set_drawable( DefaultRootWindow( X11Display_ ) );	imlib_render_pixmaps_for_whole_image( &x11Drawable_, &memoryImageAlpha_ );	imlib_context_set_image(0);	//printf( "Created a backing image of %d by %d pixels for X11Context::X11Context()\n", pixmapWidth_, pixmapHeight_ );	init();	isMemoryCtx_ = true;}X11Context::X11Context( const long& contextID ):	x11GC_(0),	x11Drawable_(0),	parentImage_(NULL),	memoryImage_(0),	memoryImageAlpha_(0){	x11Drawable_ = (Drawable)contextID;	init();}X11Context::~X11Context(){	clearBuffer();	if ( 0 != x11GC_ ) {		XFreeGC( X11Display_, x11GC_ );	}	/*	if ( (true == isMemoryCtx_) && (NULL != x11Drawable_) ) {		XFreePixmap(X11Display_, x11Drawable_);	}	*/	if ( (true == isMemoryCtx_) && (NULL != memoryImage_) ) {		imlib_context_set_image( memoryImage_ );		imlib_free_image_and_decache();		if ( NULL != x11Drawable_ ) {			imlib_free_pixmap_and_mask( x11Drawable_ );		}	}}void X11Context::init(){	pathOperations_.clear();	textOperations_.clear();	pathStarted_ = false;	isMemoryCtx_ = false;	oldOrigin_.x_ = 0.0;	oldOrigin_.y_ = 0.0;	origin_.x_ = 0.0;	origin_.y_ = 0.0;	isXORModeOn_ = false;	alignToBaseline_ = false;	X11GraphicsToolkit* toolkit = (X11GraphicsToolkit*)GraphicsToolkit::getDefaultGraphicsToolkit();	X11Display_ = toolkit->getX11Display();	createDefaultGC();}void X11Context::releaseHandle(){	clearBuffer();	if ( NULL != parentImage_ ) {		imlib_context_set_drawable( parentImage_->getPixMap() );		imlib_context_set_image( parentImage_->getXImage() );		imlib_copy_drawable_to_image( parentImage_->getAlphaMaskPixMap(), 0, 0,										parentImage_->getWidth(), parentImage_->getHeight(),										0, 0, 0 );	}	imlib_context_set_drawable(0);}void X11Context::checkHandle(){	imlib_context_set_drawable(x11Drawable_);	//printf( "X11Context::checkHandle() x11Drawable_: %p\n", x11Drawable_ );	if ( NULL != parentImage_ ) {		parentImage_->updateImageDataFromImageBits();	}}void X11Context::setCurrentFontState(VCF::FontState * state){	currentFontState_ = *state;}VCF::FontState* X11Context::getCurrentFontState(){	return &currentFontState_;}void X11Context::drawPartialImage( 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__);	}	Rect tmpBounds = *imageBounds;	tmpBounds.offset( origin_.x_, origin_.y_ );	X11Image* x11Image = reinterpret_cast<X11Image*>( image );	Imlib_Image imImage = x11Image->getXImage();	imlib_context_set_image( imImage );	int width = (int)tmpBounds.getWidth();	int height = (int)tmpBounds.getHeight();	imlib_render_image_part_on_drawable_at_size( (int)tmpBounds.left_, (int)tmpBounds.top_, width, height,												(int)(x + origin_.x_), (int)(y + origin_.y_), width, height );	imlib_context_set_image( 0 );	releaseHandle();}void X11Context::drawImageWithinBounds( Rect* bounds, Image* image ){	checkHandle();	Rect tmpBounds = *bounds;	tmpBounds.offset( origin_.x_, origin_.y_ );	X11Image* x11Image = reinterpret_cast<X11Image*>( image );	Imlib_Image imImage = x11Image->getXImage();	imlib_context_set_image( imImage );	int width = minVal<int>( (int)tmpBounds.getWidth(), image->getWidth() );	int height = minVal<int>( (int)tmpBounds.getHeight(), image->getHeight() );	imlib_render_image_part_on_drawable_at_size( 0, 0, width, height,												(int)tmpBounds.left_, (int)tmpBounds.top_,												width, height );	imlib_context_set_image( 0 );	releaseHandle();}void X11Context::drawImage( const double & x, const double & y, Image* image ){	checkHandle();	X11Image* x11Image = reinterpret_cast<X11Image*>( image );	Imlib_Image imImage = x11Image->getXImage();	imlib_context_set_image( imImage );	imlib_render_image_on_drawable( (int)(x + origin_.x_), (int)(y + origin_.y_) );	imlib_context_set_image( 0 );	releaseHandle();}void X11Context::textAt(const double & x, const double & y, const String & text, const long& drawOptions){	if ( text.empty() ) {		return;	}	checkHandle();	Font* ctxFont = context_->getCurrentFont();	if ( NULL == ctxFont ){		//throw exception	}	X11Font* fontImpl = reinterpret_cast<X11Font*>( ctxFont->getFontPeer() );	if ( NULL == fontImpl ){		//throw exception	}	int oldRed = 0;	int oldGreen = 0;	int oldBlue = 0;	int oldAlpha = 0;	imlib_context_get_color( &oldRed, &oldGreen, &oldBlue, &oldAlpha );	Imlib_Font imFont = (Imlib_Font)fontImpl->getFontHandleID();	if ( NULL == imFont ) {		throw InvalidPointerException(MAKE_ERROR_MSG_2("(Imlib_Font)fontImpl->getFontHandleID() returned NULL! in X11Context::textAt()"));	}	Color* fontColor = ctxFont->getColor();	imlib_context_set_font( imFont );	imlib_context_set_color( (int)fontColor->getRed()*255, (int)fontColor->getGreen()*255, (int)fontColor->getBlue()*255, 255 );	int textWidth = 0;	int textHeight = 0;	std::vector<String> lines;	simpleLineBreak( text, lines );	if ( !lines.empty() ) {		std::vector<String>::iterator it = lines.begin();		std::vector<int> lineHeights;		lineHeights.resize( lines.size(), 0 );		std::vector<int>::iterator lhIter = lineHeights.begin();		//calculate dimensions		while ( it != lines.end() ) {			String& lineOfText = *it;			int w = 0;			int h = 0;			imlib_get_text_size( lineOfText.c_str(), &w, &h );			textWidth = maxVal<int>( textWidth, w );			textHeight += h;			*lhIter = h;			it ++;			lhIter ++;		}		if ( textHeight > 0 && textWidth > 0 ) {			int ix = (int)(x + origin_.x_);			int iy = (int)(y + origin_.y_);			Imlib_Image oldImage = imlib_context_get_image();			Imlib_Image fontImage = imlib_create_image_frodrawable_( 0, ix, iy, textWidth, textHeight, 0 );			if ( fontImage ) {				imlib_context_set_image( fontImage );				int x = 0;				int y = 0;				std::vector<String>::iterator it = lines.begin();				std::vector<int>::iterator lhIter = lineHeights.begin();				while ( it != lines.end() ) {					String& lineOfText = *it;					imlib_text_draw( x, y, lineOfText.c_str() );					y += *lhIter;					it ++;					lhIter ++;				}				imlib_render_image_on_drawable( ix, iy );				imlib_free_image_and_decache();			}			imlib_context_set_image( oldImage );		}	}	imlib_context_set_color( oldRed, oldGreen, oldBlue, oldAlpha );	releaseHandle();}void X11Context::textBoundedBy( Rect* bounds, const String& text, const long& drawOptions ){	textAt( bounds->left_, bounds->top_, text, drawOptions );}void X11Context::arc( const double & x1, const double & y1, const double & x2, const double & y2,                      const double & x3, const double & y3, const double & x4, const double & y4 ){	testBuffer();	pathStarted_ = true;	//swap out the values to ensure they are normalized since windows is brain dead about this	double ax1 = x1;	double ay1 = y1;	double ax2 = x2;	double ay2 = y2;	double tmp = x2;	if ( ax1 > ax2 ) {		ax2 = ax1;		ax1 = tmp;	}	tmp = ay2;	if ( ay1 > ay2 ) {		ay2 = ay1;		ay1 = tmp;	}	PointOperation* newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_ARC;	newPointOp->x = ax1;	newPointOp->y = ay1;	pathOperations_.push_back( newPointOp );	newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_ARC;	newPointOp->x = ax2;	newPointOp->y = ay2;	pathOperations_.push_back( newPointOp );	newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_ARC;	newPointOp->x = x3;	newPointOp->y = y3;	pathOperations_.push_back( newPointOp );	newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_ARC;	newPointOp->x = x4;	newPointOp->y = y4;	pathOperations_.push_back( newPointOp );}void X11Context::rectangle(const double & x1, const double & y1, const double & x2, const double & y2){	testBuffer();	pathStarted_ = true;	PointOperation* newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_RECT;	newPointOp->x = x1;	newPointOp->y = y1;	pathOperations_.push_back( newPointOp );	newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_RECT;	newPointOp->x = x2;	newPointOp->y = y2;	pathOperations_.push_back( newPointOp );}void X11Context::circle(const double & x, const double & y, const double & radius){	ellipse( x - radius, y - radius, x + radius, y + radius );}void X11Context::ellipse(const double & x1, const double & y1, const double & x2, const double & y2, const double & angle){	testBuffer();	pathStarted_ = true;	//swap out the values to ensure they are normalized since windows is brain dead about this	double ax1 = x1;	double ay1 = y1;	double ax2 = x2;	double ay2 = y2;	double tmp = x2;	if ( ax1 > ax2 ) {		ax2 = ax1;		ax1 = tmp;	}	tmp = ay2;	if ( ay1 > ay2 ) {		ay2 = ay1;		ay1 = tmp;	}	PointOperation* newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_ELLIPSE;	newPointOp->x = ax1;	newPointOp->y = ay1;	pathOperations_.push_back( newPointOp );	newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_ELLIPSE;	newPointOp->x = ax2;	newPointOp->y = ay2;	pathOperations_.push_back( newPointOp );}void X11Context::setCurrentStrokeState(VCF::StrokeState * state){	currentStroke_ = *state;}void X11Context::setCurrentFillState(VCF::FillState * state){	currentFill_ = *state;}void X11Context::polyline( std::vector<Point*> & pts){	testBuffer();	pathStarted_ = true;	std::vector<Point*>::iterator it = pts.begin();	PointOperation* newPointOp = NULL;	while ( it != pts.end() ){		newPointOp = new PointOperation();		newPointOp->primitive = PRIMITIVE_POLYLINE;		newPointOp->x = (*it)->x_;		newPointOp->y = (*it)->y_;		pathOperations_.push_back( newPointOp );		it++;	}}void X11Context::curve(const double & x1, const double & y1, const double & x2, const double & y2,                         const double & x3, const double & y3, const double & x4, const double & y4 ){	testBuffer();	pathStarted_ = true;	PointOperation* newPointOp = NULL;	//start point 1	newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_BEZIER;	newPointOp->x = x1;	newPointOp->y = y1;	pathOperations_.push_back( newPointOp );	//start point 1	newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_BEZIER;	newPointOp->x = x2;	newPointOp->y = y2;	pathOperations_.push_back( newPointOp );	//start point 1	newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_BEZIER;	newPointOp->x = x3;	newPointOp->y = y3;	pathOperations_.push_back( newPointOp );	//start point 1	newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_BEZIER;	newPointOp->x = x4;	newPointOp->y = y4;	pathOperations_.push_back( newPointOp );}void X11Context::lineTo(const double & x, const double & y){	testBuffer();	pathStarted_ = true;	PointOperation* newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_LINE;	newPointOp->x = x;	newPointOp->y = y;	pathOperations_.push_back( newPointOp );}void X11Context::moveTo(const double & x, const double & y){	testBuffer();	pathStarted_ = true;	PointOperation* newPointOp = new PointOperation();	newPointOp->primitive = PRIMITIVE_MOVE;	newPointOp->x = x;	newPointOp->y = y;	pathOperations_.push_back( newPointOp );}void X11Context::testBuffer(){	/**	*means the path has been finished by a call to fill or stroke path	*/	if ( false == pathStarted_ ){		clearBuffer();	}}void X11Context::fillPath(){	checkHandle();	inFillPath_ = true;	pathStarted_ = false;	X11GraphicsToolkit* toolkit = (X11GraphicsToolkit*)GraphicsToolkit::getDefaultGraphicsToolkit();	ulong32 pixel =  toolkit->getPixelForColor( &currentFill_.Color_ );	XSetForeground ( X11Display_, x11GC_, pixel );	XSetBackground ( X11Display_, x11GC_, pixel );	imlib_context_set_color( currentFill_.Color_.getRed()*255, currentFill_.Color_.getGreen()*255, currentFill_.Color_.getBlue()*255, 0 );	XSetLineAttributes( X11Display_, x11GC_, 0, LineSolid,				CapProjecting, JoinMiter );	execPathOperations();	releaseHandle();}

⌨️ 快捷键说明

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