📄 dccg.cpp
字号:
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 status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , &chars , (ATSUStyle*) &m_macATSUIStyle , &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 ); 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 ;/* // TODO if ( m_backgroundMode == wxSOLID ) { wxGraphicPath* path = m_graphicContext->CreatePath() ; path->MoveToPoint( drawX , drawY ) ; path->AddLineToPoint( (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent)) , (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent)) ) ; path->AddLineToPoint( (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent ) + cos(angle / RAD2DEG) * FixedToInt(textAfter)) , (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent) - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ) ; path->AddLineToPoint( (int) (drawX + cos(angle / RAD2DEG) * FixedToInt(textAfter)) , (int) (drawY - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ) ; m_graphicContext->FillPath( path , m_textBackgroundColour ) ; delete path ; }*/ x += (int)(sin(angle / RAD2DEG) * FixedToInt(ascent)); y += (int)(cos(angle / RAD2DEG) * 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 wxMacCGContext::GetTextExtent( const wxString &str, wxCoord *width, wxCoord *height, wxCoord *descent, wxCoord *externalLeading ) const{ wxCHECK_RET( m_macATSUIStyle != NULL, 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 status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , &chars , (ATSUStyle*) &m_macATSUIStyle , &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 wxMacCGContext::GetPartialTextExtents(const wxString& text, wxArrayInt& 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 ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , &chars , (ATSUStyle*) &m_macATSUIStyle , &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 wxMacCGContext::SetFont( const wxFont &font ){ if ( m_macATSUIStyle ) { ::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle); m_macATSUIStyle = NULL ; } if ( font.Ok() ) { OSStatus status ; status = ATSUCreateAndCopyStyle( (ATSUStyle) font.MacGetATSUStyle() , (ATSUStyle*) &m_macATSUIStyle ) ; wxASSERT_MSG( status == noErr, wxT("couldn't create ATSU style") ) ; // we need the scale here ... Fixed atsuSize = IntToFixed( int( /*m_scaleY*/ 1 * font.MacGetFontSize()) ) ; RGBColor atsuColor = MAC_WXCOLORREF( m_textForegroundColor.GetPixel() ) ; ATSUAttributeTag atsuTags[] = { kATSUSizeTag , kATSUColorTag , } ; ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = { sizeof( Fixed ) , sizeof( RGBColor ) , } ; ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = { &atsuSize , &atsuColor , } ; status = ::ATSUSetAttributes( (ATSUStyle)m_macATSUIStyle, sizeof(atsuTags) / sizeof(ATSUAttributeTag) , atsuTags, atsuSizes, atsuValues); wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ) ; }}#pragma mark -wxDC::wxDC(){ m_ok = false ; m_colour = true; m_mm_to_pix_x = mm2pt; m_mm_to_pix_y = mm2pt; m_externalDeviceOriginX = 0; m_externalDeviceOriginY = 0; m_logicalScaleX = 1.0; m_logicalScaleY = 1.0; m_userScaleX = 1.0; m_userScaleY = 1.0; m_scaleX = 1.0; m_scaleY = 1.0; m_needComputeScaleX = m_needComputeScaleY = false; m_macPort = 0 ; m_macLocalOrigin.x = m_macLocalOrigin.y = 0 ; m_pen = *wxBLACK_PEN; m_font = *wxNORMAL_FONT; m_brush = *wxWHITE_BRUSH; m_macATSUIStyle = NULL ; m_graphicContext = NULL ;}wxDC::~wxDC(){ if ( m_macATSUIStyle ) { ::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle); m_macATSUIStyle = NULL ; } delete m_graphicContext ;}void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask ){ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawBitmap - invalid DC") ); wxCHECK_RET( bmp.Ok(), wxT("wxDC(cg)::DoDrawBitmap - invalid bitmap") ); wxCoord xx = XLOG2DEVMAC(x); wxCoord yy = YLOG2DEVMAC(y); wxCoord w = bmp.GetWidth(); wxCoord h = bmp.GetHeight(); wxCoord ww = XLOG2DEVREL(w); wxCoord hh = YLOG2DEVREL(h); if ( bmp.GetDepth()==1 ) { wxGraphicPath* path = m_graphicContext->CreatePath() ; path->AddRectangle( xx , yy , ww , hh ) ; m_graphicContext->FillPath( path , m_textBackgroundColour, wxODDEVEN_RULE) ; delete path; m_graphicContext->DrawBitmap( bmp, xx , yy , ww , hh ) ; } else { m_graphicContext->DrawBitmap( bmp, xx , yy , ww , hh ) ; }}void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ){ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawIcon - invalid DC") ); wxCHECK_RET( icon.Ok(), wxT("wxDC(cg)::DoDrawIcon - invalid icon") ); wxCoord xx = XLOG2DEVMAC(x); wxCoord yy = YLOG2DEVMAC(y); wxCoord w = icon.GetWidth(); wxCoord h = icon.GetHeight(); wxCoord ww = XLOG2DEVREL(w); wxCoord hh = YLOG2DEVREL(h); m_graphicContext->DrawIcon( icon , xx, yy, ww, hh ) ;}void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ){ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoSetClippingRegion - invalid DC") ); wxCoord xx, yy, ww, hh; xx = XLOG2DEVMAC(x); yy = YLOG2DEVMAC(y); ww = XLOG2DEVREL(width); hh = YLOG2DEVREL(height); CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ; CGRect clipRect = CGRectMake( xx , yy , ww, hh ) ; CGContextClipToRect( cgContext , clipRect ) ;// SetRectRgn( (RgnHandle) m_macCurrentClipRgn , xx , yy , xx + ww , yy + hh ) ;// SectRgn( (RgnHandle) m_macCurrentClipRgn , (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; if ( m_clipping ) { m_clipX1 = wxMax( m_clipX1, xx ); m_clipY1 = wxMax( m_clipY1, yy ); m_clipX2 = wxMin( m_clipX2, (xx + ww) ); m_clipY2 = wxMin( m_clipY2, (yy + hh) ); } else { m_clipping = true; m_clipX1 = xx; m_clipY1 = yy; m_clipX2 = xx + ww; m_clipY2 = yy + hh; } // TODO: as soon as we don't reset the context for each operation anymore // we have to update the context as well}void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ){ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoSetClippingRegionAsRegion - invalid DC") ); if (region.Empty()) { DestroyClippingRegion(); return; } wxCoord x, y, w, h; region.GetBox( x, y, w, h ); wxCoord xx, yy, ww, hh; xx = XLOG2DEVMAC(x); yy = YLOG2DEVMAC(y); ww = XLOG2DEVREL(w); hh = YLOG2DEVREL(h); // if we have a scaling that we cannot map onto native regions // we must use the box if ( ww != w || hh != h ) { wxDC::DoSetClippingRegion( x, y, w, h ); } else { if ( m_clipping ) { m_clipX1 = wxMax( m_clipX1, xx ); m_clipY1 = wxMax( m_clipY1, yy ); m_clipX2 = wxMin( m_clipX2, (xx + ww) ); m_clipY2 = wxMin( m_clipY2, (yy + hh) ); } else { m_clipping = true; m_clipX1 = xx; m_clipY1 = yy; m_clipX2 = xx + ww; m_clipY2 = yy + hh; } }}void wxDC::DestroyClippingRegion(){ CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -