📄 dc.cpp
字号:
if ( mode == kUnsupportedMode )
{
wxFAIL_MSG(wxT("unsupported blitting mode" ));
return false ;
}
CGrafPtr sourcePort = (CGrafPtr) source->m_macPort ;
PixMapHandle bmappixels = GetGWorldPixMap( sourcePort ) ;
if ( LockPixels(bmappixels) )
{
wxMacFastPortSetter helper(this) ;
if ( source->GetDepth() == 1 )
{
RGBForeColor( &MAC_WXCOLORREF(m_textForegroundColour.GetPixel()) ) ;
RGBBackColor( &MAC_WXCOLORREF(m_textBackgroundColour.GetPixel()) ) ;
}
else
{
// the modes need this, otherwise we'll end up having really nice colors...
RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF } ;
RGBColor black = { 0, 0, 0 } ;
RGBForeColor( &black ) ;
RGBBackColor( &white ) ;
}
if ( useMask && source->m_macMask )
{
if ( mode == srcCopy )
{
if ( LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) )
{
CopyMask( GetPortBitMapForCopyBits( sourcePort ) ,
GetPortBitMapForCopyBits( MAC_WXHBITMAP(source->m_macMask) ) ,
GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ) ,
&srcrect, &srcrect , &dstrect ) ;
UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ;
}
}
else
{
RgnHandle clipRgn = NewRgn() ;
LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ;
BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ;
UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ;
OffsetRgn( clipRgn , -srcrect.left + dstrect.left, -srcrect.top + dstrect.top ) ;
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 } ;
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)] =
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -