X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9b2eab527d37acf83eba4da142c0c7508d3a0993..a3ab1c18017bb08329e73918f9f502ea00cdb447:/src/mac/carbon/dc.cpp diff --git a/src/mac/carbon/dc.cpp b/src/mac/carbon/dc.cpp index 1630fd9c14..9bc9f204b5 100644 --- a/src/mac/carbon/dc.cpp +++ b/src/mac/carbon/dc.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: dc.cpp +// Name: src/mac/carbon/dc.cpp // Purpose: wxDC class // Author: Stefan Csomor // Modified by: @@ -14,13 +14,17 @@ #include "wx/dc.h" #if !wxMAC_USE_CORE_GRAPHICS -#include "wx/app.h" + +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/app.h" + #include "wx/dcmemory.h" + #include "wx/dcprint.h" + #include "wx/region.h" + #include "wx/image.h" +#endif + #include "wx/mac/uma.h" -#include "wx/dcmemory.h" -#include "wx/dcprint.h" -#include "wx/region.h" -#include "wx/image.h" -#include "wx/log.h" #ifdef __MSL__ #if __MSL__ >= 0x6000 @@ -36,6 +40,11 @@ #include #endif + +// set to 0 if problems arise +#define wxMAC_EXPERIMENTAL_DC 1 + + IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject) //----------------------------------------------------------------------------- @@ -46,11 +55,6 @@ const double RAD2DEG = 180.0 / M_PI; const short kEmulatedMode = -1 ; const short kUnsupportedMode = -2 ; -extern TECObjectRef s_TECNativeCToUnicode ; - -// set to 0 if problems arise -#define wxMAC_EXPERIMENTAL_DC 1 - wxMacPortSetter::wxMacPortSetter( const wxDC* dc ) : m_ph( (GrafPtr) dc->m_macPort ) { @@ -113,7 +117,7 @@ wxMacWindowClipper::wxMacWindowClipper( const wxWindow* win ) : if ( win->GetPeer() ) { int x = 0 , y = 0; - win->MacWindowToRootWindow( &x,&y ) ; + win->MacWindowToRootWindow( &x, &y ) ; // get area including focus rect CopyRgn( (RgnHandle) ((wxWindow*)win)->MacGetVisibleRegion(true).GetWXHRGN() , m_newClip ) ; @@ -147,13 +151,6 @@ wxMacWindowStateSaver::~wxMacWindowStateSaver() SetThemeDrawingState( m_themeDrawingState , true ) ; } -//----------------------------------------------------------------------------- -// Local functions -//----------------------------------------------------------------------------- -static inline double dmin(double a, double b) { return a < b ? a : b; } -static inline double dmax(double a, double b) { return a > b ? a : b; } -static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; } - //----------------------------------------------------------------------------- // wxDC //----------------------------------------------------------------------------- @@ -281,7 +278,6 @@ wxDC::wxDC() m_needComputeScaleY = false; m_macPort = NULL ; m_macMask = NULL ; - m_ok = false ; m_macFontInstalled = false ; m_macBrushInstalled = false ; m_macPenInstalled = false ; @@ -406,8 +402,8 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask } else { - RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF} ; - RGBColor black = { 0, 0, 0} ; + RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF } ; + RGBColor black = { 0, 0, 0 } ; RGBForeColor( &black ) ; RGBBackColor( &white ) ; } @@ -459,7 +455,7 @@ void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ) wxCoord ww = XLOG2DEVREL(w); wxCoord hh = YLOG2DEVREL(h); - Rect r = { yy , xx, yy + hh , xx + ww } ; + Rect r = { yy , xx, yy + hh, xx + ww } ; PlotIconRef( &r , kAlignNone , kTransformNone , kPlotIconRefNormalFlags , MAC_WXHICON( icon.GetHICON() ) ) ; } @@ -479,8 +475,8 @@ void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord hei { 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)); + m_clipX2 = wxMin( m_clipX2, (xx + ww) ); + m_clipY2 = wxMin( m_clipY2, (yy + hh) ); } else { @@ -492,7 +488,7 @@ void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord hei } } -void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) +void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) { wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegionAsRegion - invalid DC")); @@ -522,8 +518,8 @@ void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) { 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)); + m_clipX2 = wxMin( m_clipX2, (xx + ww) ); + m_clipY2 = wxMin( m_clipY2, (yy + hh) ); } else { @@ -750,9 +746,7 @@ bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const GetCPixel( XLOG2DEVMAC(x), YLOG2DEVMAC(y), &colour ); // convert from Mac colour to wx - col->Set( colour.red >> 8, - colour.green >> 8, - colour.blue >> 8); + col->Set( colour.red >> 8, colour.green >> 8, colour.blue >> 8); return true ; } @@ -767,7 +761,7 @@ void wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) { MacInstallPen() ; wxCoord offset = ( (m_pen.GetWidth() == 0 ? 1 : - m_pen.GetWidth() ) * (wxCoord)m_scaleX - 1) / 2; + m_pen.GetWidth() ) * (wxCoord)m_scaleX - 1) / 2; wxCoord xx1 = XLOG2DEVMAC(x1) - offset; wxCoord yy1 = YLOG2DEVMAC(y1) - offset; wxCoord xx2 = XLOG2DEVMAC(x2) - offset; @@ -862,7 +856,7 @@ void wxDC::DoDrawArc( wxCoord x1, wxCoord y1, double dx = xx1 - xxc; double dy = yy1 - yyc; - double radius = sqrt((double)(dx*dx+dy*dy)); + double radius = sqrt((double)(dx * dx + dy * dy)); wxCoord rad = (wxCoord)radius; double radius1, radius2; @@ -879,10 +873,10 @@ void wxDC::DoDrawArc( wxCoord x1, wxCoord y1, { radius1 = (xx1 - xxc == 0) ? (yy1 - yyc < 0) ? 90.0 : -90.0 : - -atan2(double(yy1-yyc), double(xx1-xxc)) * RAD2DEG; + -atan2(double(yy1 - yyc), double(xx1 - xxc)) * RAD2DEG; radius2 = (xx2 - xxc == 0) ? (yy2 - yyc < 0) ? 90.0 : -90.0 : - -atan2(double(yy2-yyc), double(xx2-xxc)) * RAD2DEG; + -atan2(double(yy2 - yyc), double(xx2 - xxc)) * RAD2DEG; } wxCoord alpha2 = wxCoord(radius2 - radius1); @@ -986,11 +980,12 @@ void wxDC::DoDrawLines(int n, wxPoint points[], MacInstallPen() ; wxCoord offset = ( (m_pen.GetWidth() == 0 ? 1 : m_pen.GetWidth() ) * (wxCoord)m_scaleX - 1) / 2 ; + wxCoord x1, x2 , y1 , y2 ; x1 = XLOG2DEVMAC(points[0].x + xoffset); y1 = YLOG2DEVMAC(points[0].y + yoffset); - ::MoveTo(x1 - offset, y1 - offset ); + ::MoveTo( x1 - offset, y1 - offset ); for (int i = 0; i < n-1; i++) { x2 = XLOG2DEVMAC(points[i + 1].x + xoffset); @@ -1007,7 +1002,7 @@ void wxDC::DoDrawPolygon(int n, wxPoint points[], if ( m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT ) return ; - + wxMacFastPortSetter helper(this) ; wxCoord x1, x2 , y1 , y2 ; @@ -1025,7 +1020,7 @@ void wxDC::DoDrawPolygon(int n, wxPoint points[], // close the polyline if necessary if ( x1 != x2 || y1 != y2 ) - ::LineTo(x1, y1 ) ; + ::LineTo( x1, y1 ) ; ClosePoly(); if (m_brush.GetStyle() != wxTRANSPARENT) @@ -1146,7 +1141,7 @@ void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height) // CMB: draw nothing if transformed w or h is 0 if (ww == 0 || hh == 0) return; - + // CMB: handle -ve width and/or height if (ww < 0) { @@ -1182,7 +1177,7 @@ bool wxDC::CanDrawBitmap(void) const bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask, - wxCoord xsrcMask, wxCoord ysrcMask ) + wxCoord xsrcMask, wxCoord ysrcMask ) { wxCHECK_MSG(Ok(), false, wxT("wxDC::DoBlit - invalid DC")); wxCHECK_MSG(source->Ok(), false, wxT("wxDC::DoBlit - invalid source DC")); @@ -1307,8 +1302,8 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, else { // the modes need this, otherwise we'll end up having really nice colors... - RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF} ; - RGBColor black = { 0, 0, 0} ; + RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF } ; + RGBColor black = { 0, 0, 0 } ; RGBForeColor( &black ) ; RGBBackColor( &white ) ; @@ -1373,7 +1368,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, GetCPixel( srcPoint.h , srcPoint.v , &srcColor ) ; SetPort( (GrafPtr) m_macPort ) ; GetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; - wxMacCalculateColour( logical_func , srcColor , dstColor ) ; + wxMacCalculateColour( logical_func , srcColor , dstColor ) ; SetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; } } @@ -1436,7 +1431,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, GetCPixel( srcPoint.h , srcPoint.v , &srcColor) ; SetPort( (GrafPtr) m_macPort ) ; GetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; - wxMacCalculateColour( logical_func , srcColor , dstColor ) ; + wxMacCalculateColour( logical_func , srcColor , dstColor ) ; SetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ; } } @@ -1469,53 +1464,21 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, double angle) { - // TODO: support text background color (only possible by hand, ATSUI does not support it) wxCHECK_RET( Ok(), wxT("wxDC::DoDrawRotatedText - invalid DC") ); - if ( str.Length() == 0 ) + if ( str.empty() ) return ; wxMacFastPortSetter helper(this) ; MacInstallFont() ; -#if 0 - if ( 0 ) - { - m_macFormerAliasState = IsAntiAliasedTextEnabled(&m_macFormerAliasSize); - SetAntiAliasedTextEnabled(true, SInt16(m_scaleY * m_font.MacGetFontSize())); - m_macAliasWasEnabled = true ; - } -#endif - 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 , + 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") ); @@ -1530,32 +1493,69 @@ void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, ATSUTextMeasurement textBefore, textAfter ; ATSUTextMeasurement ascent, descent ; - if ( abs(iAngle) > 0 ) + ATSLineLayoutOptions layoutOptions = kATSLineNoLayoutOptions ; + + if (m_font.GetNoAntiAliasing()) { - Fixed atsuAngle = IntToFixed( iAngle ) ; + layoutOptions |= kATSLineNoAntiAliasing ; + } - ATSUAttributeTag atsuTags[] = - { - kATSULineRotationTag , - } ; - ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = - { - sizeof( Fixed ) , - } ; - ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = - { - &atsuAngle , - } ; + Fixed atsuAngle = IntToFixed( iAngle ) ; + + ATSUAttributeTag atsuTags[] = + { + kATSULineLayoutOptionsTag , + kATSULineRotationTag , + } ; - status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag), + 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(); - drawX += (int)(sin(angle/RAD2DEG) * FixedToInt(ascent)); - drawY += (int)(cos(angle/RAD2DEG) * FixedToInt(ascent)); + ::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) ); @@ -1565,90 +1565,16 @@ void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y, 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); - -#if SIZEOF_WCHAR_T == 4 - free( ubuf ) ; -#endif } void wxDC::DoDrawText(const wxString& strtext, wxCoord x, wxCoord y) { - wxCHECK_RET(Ok(), wxT("wxDC::DoDrawText - invalid DC")); - - wxMacFastPortSetter helper(this) ; - long xx = XLOG2DEVMAC(x); - long yy = YLOG2DEVMAC(y); - -#if TARGET_CARBON - bool useDrawThemeText = ( DrawThemeTextBox != (void*) kUnresolvedCFragSymbolAddress ) ; - if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC ) ) || m_font.GetNoAntiAliasing() ) - useDrawThemeText = false ; -#endif - - MacInstallFont() ; - - FontInfo fi ; - ::GetFontInfo( &fi ) ; - -#if TARGET_CARBON - if ( !useDrawThemeText ) - yy += fi.ascent ; -#else - yy += fi.ascent ; -#endif - - ::TextMode( (m_backgroundMode == wxTRANSPARENT) ? srcOr : srcCopy ) ; - ::MoveTo( xx , yy ); - - int line = 0 ; - { - wxString linetext = strtext ; - -#if TARGET_CARBON - if ( useDrawThemeText ) - { - Rect frame = { - yy + line*(fi.descent + fi.ascent + fi.leading), xx , - yy + (line+1)*(fi.descent + fi.ascent + fi.leading) , xx + 10000 } ; - wxMacCFStringHolder mString( linetext , m_font.GetEncoding()) ; - - if ( m_backgroundMode != wxTRANSPARENT ) - { - Point bounds = {0, 0} ; - Rect background = frame ; - SInt16 baseline ; - ::GetThemeTextDimensions( mString, - m_font.MacGetThemeFontID() , - kThemeStateActive, - false, - &bounds, - &baseline ); - background.right = background.left + bounds.h ; - background.bottom = background.top + bounds.v ; - ::EraseRect( &background ) ; - } - - ::DrawThemeTextBox( mString, - m_font.MacGetThemeFontID() , - kThemeStateActive, - false, - &frame, - teJustLeft, - NULL ); - } - else -#endif - { - wxCharBuffer text = linetext.mb_str(wxConvLocal) ; - ::DrawText( text , 0 , strlen(text) ) ; - } - } - - ::TextMode( srcOr ) ; + DoDrawRotatedText( strtext , x , y , 0) ; } bool wxDC::CanGetTextExtent() const @@ -1658,7 +1584,8 @@ bool wxDC::CanGetTextExtent() const return true ; } -void wxDC::DoGetTextExtent( const wxString &strtext, wxCoord *width, wxCoord *height, + +void wxDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *height, wxCoord *descent, wxCoord *externalLeading , wxFont *theFont ) const { @@ -1673,51 +1600,63 @@ void wxDC::DoGetTextExtent( const wxString &strtext, wxCoord *width, wxCoord *he } MacInstallFont() ; - FontInfo fi ; - ::GetFontInfo( &fi ) ; -#if TARGET_CARBON - bool useGetThemeText = ( GetThemeTextDimensions != (void*) kUnresolvedCFragSymbolAddress ) ; - if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC ) ) || ((wxFont*)&m_font)->GetNoAntiAliasing() ) - useGetThemeText = false ; -#endif + 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( fi.descent + fi.ascent ) ; + *height = YDEV2LOGREL( FixedToInt(textAscent + textDescent) ) ; if ( descent ) - *descent =YDEV2LOGREL( fi.descent ); + *descent =YDEV2LOGREL( FixedToInt(textDescent) ); if ( externalLeading ) - *externalLeading = YDEV2LOGREL( fi.leading ) ; - - int curwidth = 0 ; + *externalLeading = 0 ; if ( width ) - { - *width = 0 ; - wxString linetext = strtext ; + *width = XDEV2LOGREL( FixedToInt(textAfter - textBefore) ) ; - if ( useGetThemeText ) - { - Point bounds = {0, 0} ; - SInt16 baseline ; - wxMacCFStringHolder mString( linetext , m_font.GetEncoding() ) ; - ThemeFontID themeFont = m_font.MacGetThemeFontID() ; - ::GetThemeTextDimensions( mString, - themeFont , - kThemeStateActive, - false, - &bounds, - &baseline ); - curwidth = bounds.h ; - } - else - { - wxCharBuffer text = linetext.mb_str(wxConvLocal) ; - curwidth = ::TextWidth( text , 0 , strlen(text) ) ; - } + ::ATSUDisposeTextLayout(atsuLayout); - if ( curwidth > *width ) - *width = XDEV2LOGREL( curwidth ) ; - } if ( theFont ) { @@ -1732,110 +1671,85 @@ bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) con wxCHECK_MSG(Ok(), false, wxT("wxDC::DoGetPartialTextExtents - invalid DC")); widths.Empty(); - widths.Add(0, text.Length()); + widths.Add(0, text.length()); - if (text.Length() == 0) + if (text.length() == 0) return false; wxMacFastPortSetter helper(this) ; MacInstallFont() ; -#if TARGET_CARBON - bool useGetThemeText = ( GetThemeTextDimensions != (void*) kUnresolvedCFragSymbolAddress ) ; - if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC ) ) || ((wxFont*)&m_font)->GetNoAntiAliasing() ) - useGetThemeText = false ; + OSStatus status = noErr ; + ATSUTextLayout atsuLayout ; - if ( useGetThemeText ) + 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()) { - // If anybody knows how to do this more efficiently yet still handle - // the fractional glyph widths that may be present when using AA - // fonts, please change it. Currently it is measuring from the - // begining of the string for each succeding substring, which is much - // slower than this should be. - for (size_t i=0; iGetNoAntiAliasing() ) - useGetThemeText = false ; - - if ( useGetThemeText ) - { - Point bounds = {0, 0} ; - SInt16 baseline ; - CFStringRef mString = CFStringCreateWithBytes( NULL , (UInt8*) text , 1 , CFStringGetSystemEncoding(), false ) ; - ::GetThemeTextDimensions( mString, - m_font.MacGetThemeFontID(), - kThemeStateActive, - false, - &bounds, - &baseline ); - CFRelease( mString ) ; - width = bounds.h ; - } - else -#endif - { - width = ::TextWidth( text , 0 , 1 ) ; - } - - return YDEV2LOGREL(width) ; + wxCoord width = 0 ; + DoGetTextExtent( wxT("g"), &width , NULL , NULL , NULL , NULL ) ; + return width ; } wxCoord wxDC::GetCharHeight(void) const { - wxCHECK_MSG(Ok(), 1, wxT("wxDC::GetCharHeight - invalid DC")); - - wxMacFastPortSetter helper(this) ; - MacInstallFont() ; - FontInfo fi ; - ::GetFontInfo( &fi ) ; - - return YDEV2LOGREL( fi.descent + fi.ascent ); + wxCoord height ; + DoGetTextExtent( wxT("g") , NULL , &height , NULL , NULL , NULL ) ; + return height ; } void wxDC::Clear(void) @@ -1859,6 +1773,7 @@ void wxDC::MacInstallFont() const // if ( m_macFontInstalled ) // return ; + Pattern blackColor ; MacSetupBackgroundForCurrentPort(m_backgroundBrush) ; if ( m_backgroundMode != wxTRANSPARENT ) @@ -1942,18 +1857,15 @@ void wxDC::MacInstallFont() const { sizeof( Fixed ) , } ; -// Boolean kTrue = true ; -// Boolean kFalse = false ; - -// ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal; ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] = { &atsuSize , } ; + status = ::ATSUSetAttributes((ATSUStyle)m_macATSUIStyle, sizeof(atsuTags)/sizeof(ATSUAttributeTag) , atsuTags, atsuSizes, atsuValues); - wxASSERT_MSG( status == noErr , wxT("couldn't Modify ATSU style") ) ; + wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ) ; } Pattern gPatterns[] = @@ -2007,19 +1919,21 @@ void wxDC::MacInstallPen() const //Pattern blackColor; // if ( m_macPenInstalled ) // return ; + RGBColor forecolor = MAC_WXCOLORREF( m_pen.GetColour().GetPixel()); RGBColor backcolor = MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()); ::RGBForeColor( &forecolor ); ::RGBBackColor( &backcolor ); ::PenNormal() ; - int penWidth = (int) (m_pen.GetWidth() * m_scaleX) ; ; + // null means only one pixel, at whatever resolution + int penWidth = (int) (m_pen.GetWidth() * m_scaleX) ; if ( penWidth == 0 ) penWidth = 1 ; ::PenSize(penWidth, penWidth); - int penStyle = m_pen.GetStyle(); Pattern pat; + int penStyle = m_pen.GetStyle(); if (penStyle == wxUSER_DASH) { // FIXME: there should be exactly 8 items in the dash @@ -2083,7 +1997,7 @@ void wxDC::MacInstallPen() const // case wxSRC_AND: // source _bitmap_ AND destination break ; - default; + default: break ; } @@ -2096,6 +2010,7 @@ void wxDC::MacInstallPen() const void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background ) { Pattern whiteColor ; + if ( background.Ok() ) { switch ( background.MacGetBrushKind() ) @@ -2108,7 +2023,7 @@ void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background ) { Rect extent ; ThemeBackgroundKind bg = background.MacGetThemeBackground( &extent ) ; - ::ApplyThemeBackground( bg , &extent ,kThemeStateActive , wxDisplayDepth() , true ) ; + ::ApplyThemeBackground( bg , &extent, kThemeStateActive , wxDisplayDepth() , true ) ; } break ; @@ -2140,10 +2055,11 @@ void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background ) void wxDC::MacInstallBrush() const { wxCHECK_RET(Ok(), wxT("Invalid DC")); - Pattern blackColor ; + // if ( m_macBrushInstalled ) // return ; - // foreground + + Pattern blackColor ; bool backgroundTransparent = (GetBackgroundMode() == wxTRANSPARENT) ; ::RGBForeColor( &MAC_WXCOLORREF( m_brush.GetColour().GetPixel()) ); ::RGBBackColor( &MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()) ); @@ -2151,7 +2067,21 @@ void wxDC::MacInstallBrush() const int brushStyle = m_brush.GetStyle(); if (brushStyle == wxSOLID) { - ::PenPat(GetQDGlobalsBlack(&blackColor)); + switch ( m_brush.MacGetBrushKind() ) + { + case kwxMacBrushTheme : + { + Pattern whiteColor ; + ::BackPat(GetQDGlobalsWhite(&whiteColor)); + ::SetThemePen( m_brush.MacGetTheme() , wxDisplayDepth() , true ) ; + } + break ; + + default : + ::PenPat(GetQDGlobalsBlack(&blackColor)); + break ; + + } } else if (m_brush.IsHatch()) { @@ -2196,7 +2126,7 @@ void wxDC::MacInstallBrush() const for ( int i = 0 ; i < 8 ; ++i ) { - pat.pat[i] = gwbits[i*alignment+0] ; + pat.pat[i] = gwbits[i * alignment + 0] ; } UnlockPixels( GetGWorldPixMap( gw ) ) ;