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 ¤tFontState_;}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( ¤tFill_.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 + -
显示快捷键?