📄 dc.cpp
字号:
::PaintRgn( clipRgn ) ; } else if ( logical_func == wxCLEAR ) { RGBColor col= { 0x0000, 0x0000, 0x0000 } ; ::RGBForeColor( &col ) ; ::PaintRgn( clipRgn ) ; } else if ( logical_func == wxINVERT ) { MacInvertRgn( clipRgn ) ; } else { for ( int y = 0 ; y < srcrect.right - srcrect.left ; ++y ) { for ( int x = 0 ; x < srcrect.bottom - srcrect.top ; ++x ) { Point dstPoint = { dstrect.top + y , dstrect.left + x } ; Point srcPoint = { srcrect.top + y , srcrect.left + x } ; if ( PtInRgn( dstPoint , clipRgn ) ) { RGBColor srcColor, dstColor ; // NOTE: Get/SetCPixel are slow! SetPort( (GrafPtr) sourcePort ) ; GetCPixel( srcPoint.h , srcPoint.v , &srcColor ) ; SetPort( (GrafPtr) m_macPort ) ; GetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; wxMacCalculateColour( logical_func , srcColor , dstColor ) ; SetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; } } } } } else { if ( invertDestinationFirst ) MacInvertRgn( clipRgn ) ; CopyBits( GetPortBitMapForCopyBits( sourcePort ) , GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ) , &srcrect, &dstrect, mode, clipRgn ) ; } DisposeRgn( clipRgn ) ; } } else { RgnHandle clipRgn = NewRgn() ; SetRectRgn( clipRgn , dstrect.left , dstrect.top , dstrect.right , dstrect.bottom ) ; if ( mode == kEmulatedMode ) { Pattern pat ; ::PenPat(GetQDGlobalsBlack(&pat)); if ( logical_func == wxSET ) { RGBColor col= { 0xFFFF, 0xFFFF, 0xFFFF } ; ::RGBForeColor( &col ) ; ::PaintRgn( clipRgn ) ; } else if ( logical_func == wxCLEAR ) { RGBColor col = { 0x0000, 0x0000, 0x0000 } ; ::RGBForeColor( &col ) ; ::PaintRgn( clipRgn ) ; } else if ( logical_func == wxINVERT ) { MacInvertRgn( clipRgn ) ; } else { for ( int y = 0 ; y < srcrect.right - srcrect.left ; ++y ) { for ( int x = 0 ; x < srcrect.bottom - srcrect.top ; ++x ) { Point dstPoint = { dstrect.top + y , dstrect.left + x } ; Point srcPoint = { srcrect.top + y , srcrect.left + x } ; { RGBColor srcColor, dstColor ; // NOTE: Get/SetCPixel are slow! SetPort( (GrafPtr) sourcePort ) ; GetCPixel( srcPoint.h , srcPoint.v , &srcColor) ; SetPort( (GrafPtr) m_macPort ) ; GetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; wxMacCalculateColour( logical_func , srcColor , dstColor ) ; SetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; } } } } } else { if ( invertDestinationFirst ) MacInvertRgn( clipRgn ) ; CopyBits( GetPortBitMapForCopyBits( sourcePort ) , GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ) , &srcrect, &dstrect, mode, NULL ) ; } DisposeRgn( clipRgn ) ; } UnlockPixels( bmappixels ) ; } m_macPenInstalled = false ; m_macBrushInstalled = false ; m_macFontInstalled = false ; return true;}void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, double angle){ wxCHECK_RET( Ok(), wxT("wxDC::DoDrawRotatedText - invalid DC") ); if ( str.empty() ) return ; wxMacFastPortSetter helper(this) ; MacInstallFont() ; OSStatus status = noErr ; ATSUTextLayout atsuLayout ; wxMacUniCharBuffer unibuf( str ) ; UniCharCount chars = unibuf.GetChars() ; status = ::ATSUCreateTextLayoutWithTextPtr( unibuf.GetBuffer() , 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 ); int drawX = XLOG2DEVMAC(x) ; int drawY = YLOG2DEVMAC(y) ; ATSUTextMeasurement textBefore, textAfter ; ATSUTextMeasurement ascent, descent ; ATSLineLayoutOptions layoutOptions = kATSLineNoLayoutOptions ; if (m_font.GetNoAntiAliasing()) { layoutOptions |= kATSLineNoAntiAliasing ; } Fixed atsuAngle = IntToFixed( iAngle ) ; ATSUAttributeTag atsuTags[] = { kATSULineLayoutOptionsTag , kATSULineRotationTag , } ; ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = { sizeof( ATSLineLayoutOptions ) , sizeof( Fixed ) , } ; ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = { &layoutOptions , &atsuAngle , } ; status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag) - ( abs(iAngle) > 0.001 ? 0 : 1), atsuTags, atsuSizes, atsuValues ) ; status = ::ATSUMeasureText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, &textBefore , &textAfter, &ascent , &descent ); wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") ); if ( m_backgroundMode == wxSOLID ) { // background painting must be done by hand, cannot be done by ATSUI wxCoord x2 , y2 ; PolyHandle polygon = OpenPoly(); ::MoveTo(drawX, drawY); x2 = (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent)) ; y2 = (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent)) ; ::LineTo(x2, y2); x2 = (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent ) + cos(angle / RAD2DEG) * FixedToInt(textAfter)) ; y2 = (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent) - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ; ::LineTo(x2, y2); x2 = (int) (drawX + cos(angle / RAD2DEG) * FixedToInt(textAfter)) ; y2 = (int) (drawY - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ; ::LineTo(x2, y2); ::LineTo( drawX, drawY) ; ClosePoly(); ::ErasePoly( polygon ); KillPoly( polygon ); } drawX += (int)(sin(angle / RAD2DEG) * FixedToInt(ascent)); drawY += (int)(cos(angle / RAD2DEG) * FixedToInt(ascent)); status = ::ATSUDrawText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, IntToFixed(drawX) , IntToFixed(drawY) ); wxASSERT_MSG( status == noErr , wxT("couldn't draw the rotated text") ); Rect rect ; status = ::ATSUMeasureTextImage( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, IntToFixed(drawX) , IntToFixed(drawY) , &rect ); wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") ); OffsetRect( &rect , -m_macLocalOrigin.x , -m_macLocalOrigin.y ) ; CalcBoundingBox(XDEV2LOG(rect.left), YDEV2LOG(rect.top) ); CalcBoundingBox(XDEV2LOG(rect.right), YDEV2LOG(rect.bottom) ); ::ATSUDisposeTextLayout(atsuLayout);}void wxDC::DoDrawText(const wxString& strtext, wxCoord x, wxCoord y){ DoDrawRotatedText( strtext , x , y , 0) ;}bool wxDC::CanGetTextExtent() const{ wxCHECK_MSG(Ok(), false, wxT("wxDC::CanGetTextExtent - invalid DC")); return true ;}void wxDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *height, wxCoord *descent, wxCoord *externalLeading , wxFont *theFont ) const{ wxCHECK_RET(Ok(), wxT("wxDC::DoGetTextExtent - invalid DC")); wxMacFastPortSetter helper(this) ; wxFont formerFont = m_font ; if ( theFont ) { // work around the constness *((wxFont*)(&m_font)) = *theFont ; } MacInstallFont() ; OSStatus status = noErr ; ATSUTextLayout atsuLayout ; wxMacUniCharBuffer unibuf( str ) ; UniCharCount chars = unibuf.GetChars() ; status = ::ATSUCreateTextLayoutWithTextPtr( unibuf.GetBuffer() , 0 , chars , chars , 1 , &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ; wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the text") ); status = ::ATSUSetTransientFontMatching( atsuLayout , true ) ; wxASSERT_MSG( status == noErr , wxT("couldn't setup transient font matching") ); ATSLineLayoutOptions layoutOptions = kATSLineNoLayoutOptions ; if (m_font.GetNoAntiAliasing()) { layoutOptions |= kATSLineNoAntiAliasing ; } ATSUAttributeTag atsuTags[] = { kATSULineLayoutOptionsTag , } ; ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = { sizeof( ATSLineLayoutOptions ) , } ; ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = { &layoutOptions , } ; status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag) , atsuTags, atsuSizes, atsuValues ) ; ATSUTextMeasurement textBefore, textAfter ; ATSUTextMeasurement textAscent, textDescent ; status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, &textBefore , &textAfter, &textAscent , &textDescent ); if ( height ) *height = YDEV2LOGREL( FixedToInt(textAscent + textDescent) ) ; if ( descent ) *descent =YDEV2LOGREL( FixedToInt(textDescent) ); if ( externalLeading ) *externalLeading = 0 ; if ( width ) *width = XDEV2LOGREL( FixedToInt(textAfter - textBefore) ) ; ::ATSUDisposeTextLayout(atsuLayout); if ( theFont ) { // work around the constness *((wxFont*)(&m_font)) = formerFont ; m_macFontInstalled = false ; }}bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const{ wxCHECK_MSG(Ok(), false, wxT("wxDC::DoGetPartialTextExtents - invalid DC")); widths.Empty(); widths.Add(0, text.length()); if (text.length() == 0) return false; wxMacFastPortSetter helper(this) ; MacInstallFont() ; OSStatus status = noErr ; ATSUTextLayout atsuLayout ; wxMacUniCharBuffer unibuf( text ) ; UniCharCount chars = unibuf.GetChars() ; status = ::ATSUCreateTextLayoutWithTextPtr( unibuf.GetBuffer() , 0 , chars , chars , 1 , &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ; wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the text") ); status = ::ATSUSetTransientFontMatching( atsuLayout , true ) ; wxASSERT_MSG( status == noErr , wxT("couldn't setup transient font matching") ); ATSLineLayoutOptions layoutOptions = kATSLineNoLayoutOptions ; if (m_font.GetNoAntiAliasing()) { layoutOptions |= kATSLineNoAntiAliasing ; } ATSUAttributeTag atsuTags[] = { kATSULineLayoutOptionsTag , } ; ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = { sizeof( ATSLineLayoutOptions ) , } ; ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = { &layoutOptions , } ; status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag) , atsuTags, atsuSizes, atsuValues ) ; 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 false; widths[pos] = XDEV2LOGREL(FixedToInt( glyphBounds.upperRight.x - glyphBounds.upperLeft.x )); } ::ATSUDisposeTextLayout(atsuLayout); return true;}wxCoord wxDC::GetCharWidth(void) const{ wxCoord width = 0 ; DoGetTextExtent( wxT("g"), &width , NULL , NULL , NULL , NULL ) ; return width ;}wxCoord wxDC::GetCharHeight(void) const{ wxCoord height ; DoGetTextExtent( wxT("g") , NULL , &height , NULL , NULL , NULL ) ; return height ;}void wxDC::Clear(void){ wxCHECK_RET(Ok(), wxT("wxDC::Clear - invalid DC")); wxMacFastPortSetter helper(this) ; Rect rect = { -31000 , -31000 , 31000 , 31000 } ; if ( m_backgroundBrush.Ok() && m_backgroundBrush.GetStyle() != wxTRANSPARENT) { ::PenNormal() ; MacSetupBackgroundForCurrentPort( m_backgroundBrush ) ; ::EraseRect( &rect ) ; }}void wxDC::MacInstallFont() const{ wxCHECK_RET(Ok(), wxT("Invalid DC")); // if ( m_macFontInstalled ) // return ; Pattern blackColor ; MacSetupBackgroundForCurrentPort(m_backgroundBrush) ; if ( m_backgroundMode != wxTRANSPARENT ) { Pattern whiteColor ; ::BackPat(GetQDGlobalsWhite(&whiteColor)); } wxASSERT( m_font.Ok() ) ; ::TextFont( m_font.MacGetFontNum() ) ; ::TextSize( (short)(m_scaleY * m_font.MacGetFontSize()) ) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -