gtkcontext.cpp

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

CPP
1,071
字号
//GTKContext.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/VCFMath.h"#include "vcf/GraphicsKit/DrawUIState.h"using namespace VCF;GTKContext::GTKContext()		: drawable_( 0 )		, gdkGC_( 0 )		, pangoCtx_( 0 )		, pangoLayout_( 0 )		, pixmapWidth_( 0 )		, pixmapHeight_( 0 )		//, pathOperations_()		//, textOperations_()		, currentMoveTo_()		, oldOrigin_()		, origin_()		, inFillPath_( false )		, isMemoryCtx_( false )		//, pathStarted_(false)		, isXORModeOn_( false )		, alignToBaseline_( false )		, context_( 0 )		, parentImage_( 0 ){	this->init();}GTKContext::GTKContext( const unsigned long& width, const unsigned long& height )		: drawable_( 0 )		, gdkGC_( 0 )		, pangoCtx_( 0 )		, pangoLayout_( 0 )		, pixmapWidth_( width )		, pixmapHeight_( height )		//, pathOperations_()		//, textOperations_()		, currentMoveTo_()		, oldOrigin_()		, origin_()		, inFillPath_( false )		, isMemoryCtx_( false )		//, pathStarted_(false)		, isXORModeOn_( false )		, alignToBaseline_( false )		, context_( 0 )		, parentImage_( 0 ){	this->init();}GTKContext::GTKContext( OSHandleID contextID )		: drawable_( reinterpret_cast<GdkDrawable*>( contextID ) )		, gdkGC_( 0 )		, pangoCtx_( 0 )		, pangoLayout_( 0 )		, pixmapWidth_( 0 )		, pixmapHeight_( 0 )		//, pathOperations_()		//, textOperations_()		, currentMoveTo_()		, oldOrigin_()		, origin_()		, inFillPath_( false )		, isMemoryCtx_( false )		//, pathStarted_(false)		, isXORModeOn_( false )		, alignToBaseline_( false )		, context_( 0 )		, parentImage_( 0 ){	this->init();}GTKContext::~GTKContext(){	if ( isMemoryCtx_ ) {		g_object_unref( drawable_ );	}	g_object_unref( gdkGC_ );	if ( pangoLayout_ ) {		g_object_unref( pangoLayout_ );	}}void GTKContext::init(){	if ( ( ! drawable_ ) and ( pixmapWidth_ > 0 ) and ( pixmapHeight_ > 0 ) ) {		//create a new one, let gdk determine the depth from the root window		drawable_ = gdk_pixmap_new( gdk_get_default_root_window(),		                            pixmapWidth_,		                            pixmapHeight_,		                            -1 );	}	if ( drawable_ ) {		gdkGC_ = gdk_gc_new( drawable_ );	}	GTKGraphicsToolkit* toolkit =	    static_cast<GTKGraphicsToolkit*>(	        GraphicsToolkit::internal_getDefaultGraphicsToolkit() );	pangoCtx_ = toolkit->getGTKPangoContext();	pangoLayout_ = pango_layout_new( pangoCtx_ );}void GTKContext::setContext( GraphicsContext* context ){	context_ = context;}GraphicsContext* GTKContext::getContext(){	return context_;}OSHandleID GTKContext::getContextID(){	return reinterpret_cast<OSHandleID>( drawable_ );}void GTKContext::setContextID( OSHandleID contextID ){	if ( isMemoryCtx_ ) {		g_object_unref( drawable_ );		isMemoryCtx_ = false;	}	drawable_ = reinterpret_cast<GdkDrawable*>( contextID );	if ( drawable_ ) {		if ( gdkGC_ ) {			g_object_unref( gdkGC_ );		}		gdkGC_ = gdk_gc_new( drawable_ );	}}void GTKContext::setClippingPath( Path* clippingPath ){	this->checkHandle();	std::vector<Point> points;	clippingPath->flattenPoints( points );	std::vector<GdkPoint> pts;	for ( std::vector<Point>::iterator pt = points.begin();	        pt != points.end();	        ++pt ) {		GdkPoint aPt;		aPt.x = gint( ( *pt ).x_ + origin_.x_ );		aPt.y = gint( ( *pt ).y_ + origin_.y_ );		pts.push_back( aPt );	}	GdkRegion* rgn =	    gdk_region_polygon( &pts[ 0 ],	                        pts.size(),	                        ( clippingPath->getWindingRule() == Path::wrEvenOdd )	                        ? GDK_EVEN_ODD_RULE	                        : GDK_WINDING_RULE );	gdk_gc_set_clip_region( gdkGC_, rgn );	this->releaseHandle();}void GTKContext::setClippingRect( Rect* clipRect ){	this->checkHandle();	GdkRectangle rect;	rect.x = gint( clipRect->left_ );	rect.y = gint( clipRect->top_ );	rect.width = gint( clipRect->getWidth() );	rect.height = gint( clipRect->getHeight() );	gdk_gc_set_clip_rectangle( gdkGC_, &rect );	this->releaseHandle();}void GTKContext::drawImage( const double& x,                            const double& y,                            Rect* imageBounds,                            Image* image ){	GTKImage * gtkImg = reinterpret_cast<GTKImage*>( image );	GdkPixbuf* pb = gtkImg->getPixbuf();	if ( ulong32( imageBounds->getWidth() ) > image->getWidth()	        or ulong32( imageBounds->getHeight() ) > image->getHeight() ) {		throw RuntimeException( MAKE_ERROR_MSG_2(		                            "Dimensions of image bounds exceed the "		                            "image itself" ) );	}	gdk_draw_pixbuf( drawable_,	                 gdkGC_,	                 pb,	                 gint( imageBounds->left_ ),	                 gint( imageBounds->top_ ),	                 gint( x + origin_.x_ ),	                 gint( y + origin_.y_ ),	                 gint( imageBounds->getWidth() ),	                 gint( imageBounds->getHeight() ),	                 GDK_RGB_DITHER_NORMAL,	                 0,	                 0 );}void GTKContext::textAt( const Rect& bounds,                         const String & text,                         const long& drawOptions ){	pango_layout_set_text( pangoLayout_, text.ansi_c_str(), text.size() );	PangoFontDescription* pf =	    reinterpret_cast<PangoFontDescription*>( context_->getCurrentFont()	                                             ->getFontPeer()	                                             ->getFontHandleID() );	pango_context_set_font_description( pangoCtx_, pf );	PangoAlignment alignment = PANGO_ALIGN_LEFT;	gint x = gint( bounds.left_ );	gint y = gint( bounds.top_ );	if ( drawOptions & GraphicsContext::tdoLeftAlign ) {		alignment = PANGO_ALIGN_LEFT;	} else if ( drawOptions & GraphicsContext::tdoCenterHorzAlign ) {		alignment = PANGO_ALIGN_CENTER;	} else if ( drawOptions & GraphicsContext::tdoRightAlign ) {		alignment = PANGO_ALIGN_RIGHT;	}	pango_layout_set_alignment( pangoLayout_, alignment );	if ( drawOptions & GraphicsContext::tdoWordWrap ) {		pango_layout_set_width( pangoLayout_, gint( bounds.getWidth() ) );	} else {		pango_layout_set_width( pangoLayout_, -1 );	}	pango_layout_context_changed( pangoLayout_ );	if ( drawOptions & GraphicsContext::tdoTopAlign ) {		//formatOptions |= DT_TOP;	} else if ( drawOptions & GraphicsContext::tdoCenterVertAlign ) {		int height = 0;		pango_layout_get_pixel_size( pangoLayout_, 0, &height );		y = gint( bounds.left_		          + ( double( bounds.getHeight() ) / 2.0		              - double( height ) / 2.0 ) );		//formatOptions |= DT_VCENTER;	} else if ( drawOptions & GraphicsContext::tdoBottomAlign ) {		int height = 0;		pango_layout_get_pixel_size( pangoLayout_, 0, &height );		y = gint( bounds.left_ + ( bounds.getHeight() - height ) );	}	gdk_draw_layout( drawable_, gdkGC_, x, y, pangoLayout_ );}double GTKContext::getTextWidth( const String& text ){	pango_layout_set_text( pangoLayout_, text.ansi_c_str(), text.size() );	int width = 0;	pango_layout_get_pixel_size( pangoLayout_, &width, 0 );	return width;}double GTKContext::getTextHeight( const String& text ){	int height = 0;	pango_layout_get_pixel_size( pangoLayout_, 0, &height );	return height;}void GTKContext::rectangle( const double & x1,                            const double & y1,                            const double & x2,                            const double & y2 ){	Rect r( x1, y1, x2, y2 );	r.offset( origin_.x_, origin_.y_ );	gdk_draw_rectangle( drawable_,	                    gdkGC_,	                    inFillPath_,	                    gint( r.left_ ),	                    gint( r.top_ ),	                    gint( r.getWidth() ),	                    gint( r.getHeight() ) );}void GTKContext::ellipse( const double & x1,                          const double & y1,                          const double & x2,                          const double & y2 ){	Rect r( x1, y1, x2, y2 );	r.offset( origin_.x_, origin_.y_ );	gdk_draw_arc( drawable_,	              gdkGC_,	              inFillPath_,	              gint( r.left_ ),	              gint( r.top_ ),	              gint( r.getWidth() ),	              gint( r.getHeight() ),	              0,	              360 * 64 );}void GTKContext::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 ){	//swap out the values to ensure they are normalized since windows is	//brain dead about this}void GTKContext::polyline( const std::vector<Point>& pts ){	std::vector<GdkPoint> xPts;	xPts.resize( pts.size(), GdkPoint() );	std::vector<GdkPoint>::iterator ptIt = xPts.begin();	for ( std::vector<Point>::const_iterator it = pts.begin();	        it != pts.end();	        ++it, ++ptIt ) {		( *ptIt ).x = gint( ( *it ).x_ + origin_.x_ );		( *ptIt ).y = gint( ( *it ).y_ + origin_.y_ );	}	if ( !xPts.empty() ) {		if ( inFillPath_ ) {			gdk_draw_polygon( drawable_,

⌨️ 快捷键说明

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