📄 graphics.cpp
字号:
void wxMacCoreGraphicsContext::PopState(){ EnsureIsValid(); CGContextRestoreGState( m_cgContext );}void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDouble y ){ DrawText(str, x, y, 0.0);}void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDouble y, wxDouble angle ){ if ( m_font.IsNull() ) return; EnsureIsValid(); OSStatus status = noErr; ATSUTextLayout atsuLayout; UniCharCount chars = str.length(); UniChar* ubuf = NULL;#if SIZEOF_WCHAR_T == 4 wxMBConvUTF16 converter;#if wxUSE_UNICODE size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ); ubuf = (UniChar*) malloc( unicharlen + 2 ); converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 );#else const wxWCharBuffer wchar = str.wc_str( wxConvLocal ); size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ); ubuf = (UniChar*) malloc( unicharlen + 2 ); converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 );#endif chars = unicharlen / 2;#else#if wxUSE_UNICODE ubuf = (UniChar*) str.wc_str();#else wxWCharBuffer wchar = str.wc_str( wxConvLocal ); chars = wxWcslen( wchar.data() ); ubuf = (UniChar*) wchar.data();#endif#endif ATSUStyle style = (((wxMacCoreGraphicsFontData*)m_font.GetRefData())->GetATSUStyle()); status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , &chars , &style , &atsuLayout ); wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the rotated text") ); status = ::ATSUSetTransientFontMatching( atsuLayout , true ); wxASSERT_MSG( status == noErr , wxT("couldn't setup transient font matching") ); int iAngle = int( angle * RAD2DEG ); if ( abs(iAngle) > 0 ) { Fixed atsuAngle = IntToFixed( iAngle ); ATSUAttributeTag atsuTags[] = { kATSULineRotationTag , }; ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = { sizeof( Fixed ) , }; ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = { &atsuAngle , }; status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags) / sizeof(ATSUAttributeTag), atsuTags, atsuSizes, atsuValues ); } { ATSUAttributeTag atsuTags[] = { kATSUCGContextTag , }; ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = { sizeof( CGContextRef ) , }; ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = { &m_cgContext , }; status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags) / sizeof(ATSUAttributeTag), atsuTags, atsuSizes, atsuValues ); } ATSUTextMeasurement textBefore, textAfter; ATSUTextMeasurement ascent, descent; status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, &textBefore , &textAfter, &ascent , &descent ); wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") ); Rect rect; x += (int)(sin(angle) * FixedToInt(ascent)); y += (int)(cos(angle) * FixedToInt(ascent)); status = ::ATSUMeasureTextImage( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, IntToFixed(x) , IntToFixed(y) , &rect ); wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") ); CGContextSaveGState(m_cgContext); CGContextTranslateCTM(m_cgContext, x, y); CGContextScaleCTM(m_cgContext, 1, -1); status = ::ATSUDrawText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, IntToFixed(0) , IntToFixed(0) ); wxASSERT_MSG( status == noErr , wxT("couldn't draw the rotated text") ); CGContextRestoreGState(m_cgContext); ::ATSUDisposeTextLayout(atsuLayout);#if SIZEOF_WCHAR_T == 4 free( ubuf );#endif}void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height, wxDouble *descent, wxDouble *externalLeading ) const{ wxCHECK_RET( !m_font.IsNull(), wxT("wxDC(cg)::DoGetTextExtent - no valid font set") ); OSStatus status = noErr; ATSUTextLayout atsuLayout; UniCharCount chars = str.length(); UniChar* ubuf = NULL;#if SIZEOF_WCHAR_T == 4 wxMBConvUTF16 converter;#if wxUSE_UNICODE size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ); ubuf = (UniChar*) malloc( unicharlen + 2 ); converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 );#else const wxWCharBuffer wchar = str.wc_str( wxConvLocal ); size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ); ubuf = (UniChar*) malloc( unicharlen + 2 ); converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 );#endif chars = unicharlen / 2;#else#if wxUSE_UNICODE ubuf = (UniChar*) str.wc_str();#else wxWCharBuffer wchar = str.wc_str( wxConvLocal ); chars = wxWcslen( wchar.data() ); ubuf = (UniChar*) wchar.data();#endif#endif ATSUStyle style = (((wxMacCoreGraphicsFontData*)m_font.GetRefData())->GetATSUStyle()); status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , &chars , &style , &atsuLayout ); wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the text") ); ATSUTextMeasurement textBefore, textAfter; ATSUTextMeasurement textAscent, textDescent; status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, &textBefore , &textAfter, &textAscent , &textDescent ); if ( height ) *height = FixedToInt(textAscent + textDescent); if ( descent ) *descent = FixedToInt(textDescent); if ( externalLeading ) *externalLeading = 0; if ( width ) *width = FixedToInt(textAfter - textBefore); ::ATSUDisposeTextLayout(atsuLayout);}void wxMacCoreGraphicsContext::GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const{ widths.Empty(); widths.Add(0, text.length()); if (text.empty()) return; ATSUTextLayout atsuLayout; UniCharCount chars = text.length(); UniChar* ubuf = NULL;#if SIZEOF_WCHAR_T == 4 wxMBConvUTF16 converter;#if wxUSE_UNICODE size_t unicharlen = converter.WC2MB( NULL , text.wc_str() , 0 ); ubuf = (UniChar*) malloc( unicharlen + 2 ); converter.WC2MB( (char*) ubuf , text.wc_str(), unicharlen + 2 );#else const wxWCharBuffer wchar = text.wc_str( wxConvLocal ); size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ); ubuf = (UniChar*) malloc( unicharlen + 2 ); converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 );#endif chars = unicharlen / 2;#else#if wxUSE_UNICODE ubuf = (UniChar*) text.wc_str();#else wxWCharBuffer wchar = text.wc_str( wxConvLocal ); chars = wxWcslen( wchar.data() ); ubuf = (UniChar*) wchar.data();#endif#endif ATSUStyle style = (((wxMacCoreGraphicsFontData*)m_font.GetRefData())->GetATSUStyle()); ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , &chars , &style , &atsuLayout ); for ( int pos = 0; pos < (int)chars; pos ++ ) { unsigned long actualNumberOfBounds = 0; ATSTrapezoid glyphBounds; // We get a single bound, since the text should only require one. If it requires more, there is an issue OSStatus result; result = ATSUGetGlyphBounds( atsuLayout, 0, 0, kATSUFromTextBeginning, pos + 1, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ); if (result != noErr || actualNumberOfBounds != 1 ) return; widths[pos] = FixedToInt( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ); //unsigned char uch = s[i]; } ::ATSUDisposeTextLayout(atsuLayout);}void * wxMacCoreGraphicsContext::GetNativeContext(){ return m_cgContext;}// concatenates this transform with the current transform of this contextvoid wxMacCoreGraphicsContext::ConcatTransform( const wxGraphicsMatrix& matrix ){ if ( m_cgContext ) CGContextConcatCTM( m_cgContext, *(CGAffineTransform*) matrix.GetNativeMatrix()); else m_windowTransform = CGAffineTransformConcat(m_windowTransform, *(CGAffineTransform*) matrix.GetNativeMatrix());}// sets the transform of this contextvoid wxMacCoreGraphicsContext::SetTransform( const wxGraphicsMatrix& matrix ){ if ( m_cgContext ) { CGAffineTransform transform = CGContextGetCTM( m_cgContext ); transform = CGAffineTransformInvert( transform ) ; CGContextConcatCTM( m_cgContext, transform); CGContextConcatCTM( m_cgContext, *(CGAffineTransform*) matrix.GetNativeMatrix()); } else { m_windowTransform = *(CGAffineTransform*) matrix.GetNativeMatrix(); }}// gets the matrix of this contextwxGraphicsMatrix wxMacCoreGraphicsContext::GetTransform() const{ wxGraphicsMatrix m = CreateMatrix(); *((CGAffineTransform*) m.GetNativeMatrix()) = ( m_cgContext == NULL ? m_windowTransform : CGContextGetCTM( m_cgContext )); return m;}//// Renderer////-----------------------------------------------------------------------------// wxMacCoreGraphicsRenderer declaration//-----------------------------------------------------------------------------class WXDLLIMPEXP_CORE wxMacCoreGraphicsRenderer : public wxGraphicsRenderer{public : wxMacCoreGraphicsRenderer() {} virtual ~wxMacCoreGraphicsRenderer() {} // Context virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc); virtual wxGraphicsContext * CreateContextFromNativeContext( void * context ); virtual wxGraphicsContext * CreateContextFromNativeWindow( void * window ); virtual wxGraphicsContext * CreateContext( wxWindow* window ); virtual wxGraphicsContext * CreateMeasuringContext(); // Path virtual wxGraphicsPath CreatePath(); // Matrix virtual wxGraphicsMatrix CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, wxDouble tx=0.0, wxDouble ty=0.0); virtual wxGraphicsPen CreatePen(const wxPen& pen) ; virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) ; // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2) ; // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc) // with radius r and color cColor virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, const wxColour &oColor, const wxColour &cColor) ; // sets the font virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ;private : DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacCoreGraphicsRenderer)} ;//-----------------------------------------------------------------------------// wxMacCoreGraphicsRenderer implementation//-----------------------------------------------------------------------------IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsRenderer,wxGraphicsRenderer)static wxMacCoreGraphicsRenderer gs_MacCoreGraphicsRenderer;wxGraphicsRenderer* wxGraphicsRenderer::GetDefaultRenderer(){ return &gs_MacCoreGraphicsRenderer;}wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc){ return new wxMacCoreGraphicsContext(this,(CGContextRef)dc.GetWindow()->MacGetCGContextRef() );}wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContextFromNativeContext( void * context ){ return new wxMacCoreGraphicsContext(this,(CGContextRef)context);}wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContextFromNativeWindow( void * window ){ return new wxMacCoreGraphicsContext(this,(WindowRef)window);}wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( wxWindow* window ){ return new wxMacCoreGraphicsContext(this, window );}wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateMeasuringContext(){ return new wxMacCoreGraphicsContext(this);}// PathwxGraphicsPath wxMacCoreGraphicsRenderer::CreatePath(){ wxGraphicsPath m; m.SetRefData( new wxMacCoreGraphicsPathData(this)); return m;}// MatrixwxGraphicsMatrix wxMacCoreGraphicsRenderer::CreateMatrix( wxDouble a, wxDouble b, wxDouble c, wxDouble d, wxDouble tx, wxDouble ty){ wxGraphicsMatrix m; wxMacCoreGraphicsMatrixData* data = new wxMacCoreGraphicsMatrixData( this ); data->Set( a,b,c,d,tx,ty ) ; m.SetRefData(data); return m;}wxGraphicsPen wxMacCoreGraphicsRenderer::CreatePen(const wxPen& pen){ if ( !pen.Ok() || pen.GetStyle() == wxTRANSPARENT ) return wxNullGraphicsPen; else { wxGraphicsPen p; p.SetRefData(new wxMacCoreGraphicsPenData( this, pen )); return p; }}wxGraphicsBrush wxMacCo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -