📄 graphics.cpp
字号:
/////////////////////////////////////////////////////////////////////////////// Name: src/mac/carbon/dccg.cpp// Purpose: wxDC class// Author: Stefan Csomor// Modified by:// Created: 01/02/97// RCS-ID: $Id: graphics.cpp,v 1.34 2006/12/05 23:42:43 RD Exp $// Copyright: (c) Stefan Csomor// Licence: wxWindows licence/////////////////////////////////////////////////////////////////////////////#include "wx/wxprec.h"#if wxUSE_GRAPHICS_CONTEXT && wxMAC_USE_CORE_GRAPHICS#include "wx/graphics.h"#ifndef WX_PRECOMP #include "wx/dcclient.h" #include "wx/log.h" #include "wx/region.h"#endif#include "wx/mac/uma.h"#ifdef __MSL__ #if __MSL__ >= 0x6000 #include "math.h" // in case our functions were defined outside std, we make it known all the same namespace std { } using namespace std; #endif#endif#include "wx/mac/private.h"#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4typedef float CGFloat;#endif#ifndef wxMAC_USE_CORE_GRAPHICS_BLEND_MODES#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 #define wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 1#else #define wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 0#endif#endif//-----------------------------------------------------------------------------// constants//-----------------------------------------------------------------------------#if !defined( __DARWIN__ ) || defined(__MWERKS__)#ifndef M_PIconst double M_PI = 3.14159265358979;#endif#endifstatic const double RAD2DEG = 180.0 / M_PI;//// Pen, Brushes and Fonts//#pragma mark -#pragma mark wxMacCoreGraphicsPattern, ImagePattern, HatchPattern classes// CGPattern wrapper class: always allocate on heap, never call destructorclass wxMacCoreGraphicsPattern{public : wxMacCoreGraphicsPattern() {} // is guaranteed to be called only with a non-Null CGContextRef virtual void Render( CGContextRef ctxRef ) = 0; operator CGPatternRef() const { return m_patternRef; }protected : virtual ~wxMacCoreGraphicsPattern() { // as this is called only when the m_patternRef is been released; // don't release it again } static void _Render( void *info, CGContextRef ctxRef ) { wxMacCoreGraphicsPattern* self = (wxMacCoreGraphicsPattern*) info; if ( self && ctxRef ) self->Render( ctxRef ); } static void _Dispose( void *info ) { wxMacCoreGraphicsPattern* self = (wxMacCoreGraphicsPattern*) info; delete self; } CGPatternRef m_patternRef; static const CGPatternCallbacks ms_Callbacks;};const CGPatternCallbacks wxMacCoreGraphicsPattern::ms_Callbacks = { 0, &wxMacCoreGraphicsPattern::_Render, &wxMacCoreGraphicsPattern::_Dispose };class ImagePattern : public wxMacCoreGraphicsPattern{public : ImagePattern( const wxBitmap* bmp , const CGAffineTransform& transform ) { wxASSERT( bmp && bmp->Ok() ); Init( (CGImageRef) bmp->CGImageCreate() , transform ); } // ImagePattern takes ownership of CGImageRef passed in ImagePattern( CGImageRef image , const CGAffineTransform& transform ) { if ( image ) CFRetain( image ); Init( image , transform ); } virtual void Render( CGContextRef ctxRef ) { if (m_image != NULL) HIViewDrawCGImage( ctxRef, &m_imageBounds, m_image ); }protected : void Init( CGImageRef image, const CGAffineTransform& transform ) { m_image = image; if ( m_image ) { m_imageBounds = CGRectMake( 0.0, 0.0, (CGFloat)CGImageGetWidth( m_image ), (CGFloat)CGImageGetHeight( m_image ) ); m_patternRef = CGPatternCreate( this , m_imageBounds, transform , m_imageBounds.size.width, m_imageBounds.size.height, kCGPatternTilingNoDistortion, true , &wxMacCoreGraphicsPattern::ms_Callbacks ); } } virtual ~ImagePattern() { if ( m_image ) CGImageRelease( m_image ); } CGImageRef m_image; CGRect m_imageBounds;};class HatchPattern : public wxMacCoreGraphicsPattern{public : HatchPattern( int hatchstyle, const CGAffineTransform& transform ) { m_hatch = hatchstyle; m_imageBounds = CGRectMake( 0.0, 0.0, 8.0 , 8.0 ); m_patternRef = CGPatternCreate( this , m_imageBounds, transform , m_imageBounds.size.width, m_imageBounds.size.height, kCGPatternTilingNoDistortion, false , &wxMacCoreGraphicsPattern::ms_Callbacks ); } void StrokeLineSegments( CGContextRef ctxRef , const CGPoint pts[] , size_t count ) {#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 if ( CGContextStrokeLineSegments!=NULL ) { CGContextStrokeLineSegments( ctxRef , pts , count ); } else#endif { CGContextBeginPath( ctxRef ); for (size_t i = 0; i < count; i += 2) { CGContextMoveToPoint(ctxRef, pts[i].x, pts[i].y); CGContextAddLineToPoint(ctxRef, pts[i+1].x, pts[i+1].y); } CGContextStrokePath(ctxRef); } } virtual void Render( CGContextRef ctxRef ) { switch ( m_hatch ) { case wxBDIAGONAL_HATCH : { CGPoint pts[] = { { 8.0 , 0.0 } , { 0.0 , 8.0 } }; StrokeLineSegments( ctxRef , pts , 2 ); } break; case wxCROSSDIAG_HATCH : { CGPoint pts[] = { { 0.0 , 0.0 } , { 8.0 , 8.0 } , { 8.0 , 0.0 } , { 0.0 , 8.0 } }; StrokeLineSegments( ctxRef , pts , 4 ); } break; case wxFDIAGONAL_HATCH : { CGPoint pts[] = { { 0.0 , 0.0 } , { 8.0 , 8.0 } }; StrokeLineSegments( ctxRef , pts , 2 ); } break; case wxCROSS_HATCH : { CGPoint pts[] = { { 0.0 , 4.0 } , { 8.0 , 4.0 } , { 4.0 , 0.0 } , { 4.0 , 8.0 } , }; StrokeLineSegments( ctxRef , pts , 4 ); } break; case wxHORIZONTAL_HATCH : { CGPoint pts[] = { { 0.0 , 4.0 } , { 8.0 , 4.0 } , }; StrokeLineSegments( ctxRef , pts , 2 ); } break; case wxVERTICAL_HATCH : { CGPoint pts[] = { { 4.0 , 0.0 } , { 4.0 , 8.0 } , }; StrokeLineSegments( ctxRef , pts , 2 ); } break; default: break; } }protected : virtual ~HatchPattern() {} CGRect m_imageBounds; int m_hatch;};class wxMacCoreGraphicsPenData : public wxGraphicsObjectRefData{public: wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer, const wxPen &pen ); ~wxMacCoreGraphicsPenData(); void Init(); virtual void Apply( wxGraphicsContext* context ); virtual wxDouble GetWidth() { return m_width; }protected : CGLineCap m_cap; wxMacCFRefHolder<CGColorRef> m_color; wxMacCFRefHolder<CGColorSpaceRef> m_colorSpace; CGLineJoin m_join; CGFloat m_width; int m_count; const CGFloat *m_lengths; CGFloat *m_userLengths; bool m_isPattern; wxMacCFRefHolder<CGPatternRef> m_pattern; CGFloat* m_patternColorComponents;};wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer, const wxPen &pen ) : wxGraphicsObjectRefData( renderer ){ Init(); float components[4] = { pen.GetColour().Red() / 255.0 , pen.GetColour().Green() / 255.0 , pen.GetColour().Blue() / 255.0 , pen.GetColour().Alpha() / 255.0 } ; m_color.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ) ; // TODO: * m_dc->m_scaleX m_width = pen.GetWidth(); if (m_width <= 0.0) m_width = 0.1; switch ( pen.GetCap() ) { case wxCAP_ROUND : m_cap = kCGLineCapRound; break; case wxCAP_PROJECTING : m_cap = kCGLineCapSquare; break; case wxCAP_BUTT : m_cap = kCGLineCapButt; break; default : m_cap = kCGLineCapButt; break; } switch ( pen.GetJoin() ) { case wxJOIN_BEVEL : m_join = kCGLineJoinBevel; break; case wxJOIN_MITER : m_join = kCGLineJoinMiter; break; case wxJOIN_ROUND : m_join = kCGLineJoinRound; break; default : m_join = kCGLineJoinMiter; break; } const CGFloat dashUnit = m_width < 1.0 ? 1.0 : m_width; const CGFloat dotted[] = { dashUnit , dashUnit + 2.0 }; static const CGFloat short_dashed[] = { 9.0 , 6.0 }; static const CGFloat dashed[] = { 19.0 , 9.0 }; static const CGFloat dotted_dashed[] = { 9.0 , 6.0 , 3.0 , 3.0 }; switch ( pen.GetStyle() ) { case wxSOLID : break; case wxDOT : m_count = WXSIZEOF(dotted); m_userLengths = new CGFloat[ m_count ] ; memcpy( m_userLengths, dotted, sizeof(dotted) ); m_lengths = m_userLengths; break; case wxLONG_DASH : m_count = WXSIZEOF(dashed); m_lengths = dashed; break; case wxSHORT_DASH : m_count = WXSIZEOF(short_dashed); m_lengths = short_dashed; break; case wxDOT_DASH : m_count = WXSIZEOF(dotted_dashed); m_lengths = dotted_dashed; break; case wxUSER_DASH : wxDash *dashes; m_count = pen.GetDashes( &dashes ); if ((dashes != NULL) && (m_count > 0)) { m_userLengths = new CGFloat[m_count]; for ( int i = 0; i < m_count; ++i ) { m_userLengths[i] = dashes[i] * dashUnit; if ( i % 2 == 1 && m_userLengths[i] < dashUnit + 2.0 ) m_userLengths[i] = dashUnit + 2.0; else if ( i % 2 == 0 && m_userLengths[i] < dashUnit ) m_userLengths[i] = dashUnit; } } m_lengths = m_userLengths; break; case wxSTIPPLE : { wxBitmap* bmp = pen.GetStipple(); if ( bmp && bmp->Ok() ) { m_colorSpace.Set( CGColorSpaceCreatePattern( NULL ) ); m_pattern.Set( *( new ImagePattern( bmp , CGAffineTransformMakeScale( 1,-1 ) ) ) ); m_patternColorComponents = new CGFloat[1] ; m_patternColorComponents[0] = 1.0; m_isPattern = true; } } break; default : {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -