/////////////////////////////////////////////////////////////////////////////
-// Name: dc.cpp
+// Name: src/mac/carbon/dc.cpp
// Purpose: wxDC class
// Author: Stefan Csomor
// Modified by:
#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
#include <TextEncodingConverter.h>
#endif
+
+// set to 0 if problems arise
+#define wxMAC_EXPERIMENTAL_DC 1
+
+
IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
//-----------------------------------------------------------------------------
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 )
{
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 ) ;
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
//-----------------------------------------------------------------------------
{
m_ok = false;
m_colour = true;
- m_mm_to_pix_x = mm2pt;
- m_mm_to_pix_y = mm2pt;
- m_internalDeviceOriginX = 0;
- m_internalDeviceOriginY = 0;
- 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 = false;
- m_needComputeScaleY = false;
m_macPort = NULL ;
m_macMask = NULL ;
m_macFontInstalled = false ;
m_macBrushInstalled = false ;
m_macPenInstalled = false ;
- m_macLocalOrigin.x = m_macLocalOrigin.y = 0 ;
m_macBoundaryClipRgn = NewRgn() ;
m_macCurrentClipRgn = NewRgn() ;
SetRectRgn( (RgnHandle) m_macBoundaryClipRgn , -32000 , -32000 , 32000 , 32000 ) ;
}
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 ) ;
}
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() ) ) ;
}
{
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
{
}
}
-void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion )
+void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion )
{
wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegionAsRegion - invalid DC"));
{
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
{
m_macFontInstalled = false ;
}
-void wxDC::SetMapMode( int mode )
-{
- switch (mode)
- {
- case wxMM_TWIPS:
- SetLogicalScale( twips2mm * m_mm_to_pix_x, twips2mm * m_mm_to_pix_y );
- break;
-
- case wxMM_POINTS:
- SetLogicalScale( pt2mm * m_mm_to_pix_x, pt2mm * m_mm_to_pix_y );
- break;
-
- case wxMM_METRIC:
- SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
- break;
-
- case wxMM_LOMETRIC:
- SetLogicalScale( m_mm_to_pix_x / 10.0, m_mm_to_pix_y / 10.0 );
- break;
-
- default:
- case wxMM_TEXT:
- SetLogicalScale( 1.0, 1.0 );
- break;
- }
-
- if (mode != wxMM_TEXT)
- {
- m_needComputeScaleX = true;
- m_needComputeScaleY = true;
- }
-}
-
-void wxDC::SetUserScale( double x, double y )
-{
- // allow negative ? -> no
- m_userScaleX = x;
- m_userScaleY = y;
- ComputeScaleAndOrigin();
-}
-
-void wxDC::SetLogicalScale( double x, double y )
-{
- // allow negative ?
- m_logicalScaleX = x;
- m_logicalScaleY = y;
- ComputeScaleAndOrigin();
-}
-
-void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y )
-{
- // is this still correct ?
- m_logicalOriginX = x * m_signX;
- m_logicalOriginY = y * m_signY;
- ComputeScaleAndOrigin();
-}
-
-void wxDC::SetDeviceOrigin( wxCoord x, wxCoord y )
-{
- m_externalDeviceOriginX = x;
- m_externalDeviceOriginY = y;
- ComputeScaleAndOrigin();
-}
-
-void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
-{
- m_signX = (xLeftRight ? 1 : -1);
- m_signY = (yBottomUp ? -1 : 1);
- ComputeScaleAndOrigin();
-}
-
wxSize wxDC::GetPPI() const
{
return wxSize(72, 72);
return 1 ;
}
-void wxDC::ComputeScaleAndOrigin()
-{
- // CMB: copy scale to see if it changes
- double origScaleX = m_scaleX;
- double origScaleY = m_scaleY;
- m_scaleX = m_logicalScaleX * m_userScaleX;
- m_scaleY = m_logicalScaleY * m_userScaleY;
- m_deviceOriginX = m_internalDeviceOriginX + m_externalDeviceOriginX;
- m_deviceOriginY = m_internalDeviceOriginY + m_externalDeviceOriginY;
-
- // CMB: if scale has changed call SetPen to recalulate the line width
- if (m_scaleX != origScaleX || m_scaleY != origScaleY)
- {
- // this is a bit artificial, but we need to force wxDC to think
- // the pen has changed
- wxPen pen(GetPen());
- m_pen = wxNullPen;
- SetPen(pen);
- }
-}
-
void wxDC::SetPalette( const wxPalette& palette )
{
}
GetCPixel( XLOG2DEVMAC(x), YLOG2DEVMAC(y), &colour );
// convert from Mac colour to wx
- col->Set( colour.red >> 8,
- colour.green >> 8,
- colour.blue >> 8);
+ *col = colour;
return true ;
}
{
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;
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;
{
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);
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);
if ( m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT )
return ;
-
+
wxMacFastPortSetter helper(this) ;
wxCoord x1, x2 , y1 , y2 ;
// close the polyline if necessary
if ( x1 != x2 || y1 != y2 )
- ::LineTo(x1, y1 ) ;
+ ::LineTo( x1, y1 ) ;
ClosePoly();
if (m_brush.GetStyle() != wxTRANSPARENT)
// 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)
{
return true ;
}
-bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
+bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord dstWidth, wxCoord dstHeight,
wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask,
- wxCoord xsrcMask, wxCoord ysrcMask )
+ wxCoord xsrcMask, wxCoord ysrcMask )
+{
+ return DoStretchBlit( xdest, ydest, dstWidth, dstHeight,
+ source, xsrc, ysrc, dstWidth, dstHeight,
+ logical_func, useMask,
+ xsrcMask, ysrcMask );
+}
+
+bool wxDC::DoStretchBlit(wxCoord xdest, wxCoord ydest,
+ wxCoord dstWidth, wxCoord dstHeight,
+ wxDC *source,
+ wxCoord xsrc, wxCoord ysrc,
+ wxCoord srcWidth, wxCoord srcHeight,
+ int logical_func, bool useMask,
+ wxCoord xsrcMask, wxCoord ysrcMask)
{
- wxCHECK_MSG(Ok(), false, wxT("wxDC::DoBlit - invalid DC"));
- wxCHECK_MSG(source->Ok(), false, wxT("wxDC::DoBlit - invalid source DC"));
+ wxCHECK_MSG(Ok(), false, wxT("wxDC::DoStretchBlit - invalid DC"));
+ wxCHECK_MSG(source->Ok(), false, wxT("wxDC::DoStretchBlit - invalid source DC"));
if ( logical_func == wxNO_OP )
return true ;
Rect srcrect , dstrect ;
srcrect.top = source->YLOG2DEVMAC(ysrc) ;
srcrect.left = source->XLOG2DEVMAC(xsrc) ;
- srcrect.right = source->XLOG2DEVMAC(xsrc + width ) ;
- srcrect.bottom = source->YLOG2DEVMAC(ysrc + height) ;
+ srcrect.right = source->XLOG2DEVMAC(xsrc + srcWidth ) ;
+ srcrect.bottom = source->YLOG2DEVMAC(ysrc + srcHeight) ;
dstrect.top = YLOG2DEVMAC(ydest) ;
dstrect.left = XLOG2DEVMAC(xdest) ;
- dstrect.bottom = YLOG2DEVMAC(ydest + height ) ;
- dstrect.right = XLOG2DEVMAC(xdest + width ) ;
+ dstrect.bottom = YLOG2DEVMAC(ydest + dstHeight ) ;
+ dstrect.right = XLOG2DEVMAC(xdest + dstWidth ) ;
short mode = kUnsupportedMode ;
bool invertDestinationFirst = false ;
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 ) ;
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 ) ;
}
}
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 ) ;
}
}
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") );
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 ,
+ } ;
+
+ 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),
+ 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();
- drawX += (int)(sin(angle/RAD2DEG) * FixedToInt(ascent));
- drawY += (int)(cos(angle/RAD2DEG) * FixedToInt(ascent));
+ ::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) );
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 ) ;
+
+ OffsetRect( &rect , -m_deviceLocalOriginX , -m_deviceLocalOriginY ) ;
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
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
+ const wxFont *theFont ) const
{
wxCHECK_RET(Ok(), wxT("wxDC::DoGetTextExtent - invalid DC"));
}
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 )
{
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 ;
+
+ 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 ( useGetThemeText )
+ 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; i<text.Length(); i++)
- {
- wxString str(text.Left(i + 1));
- Point bounds = {0, 0};
- SInt16 baseline ;
- wxMacCFStringHolder mString(str, m_font.GetEncoding());
-
- ::GetThemeTextDimensions( mString,
- m_font.MacGetThemeFontID(),
- kThemeStateActive,
- false,
- &bounds,
- &baseline );
- widths[i] = XDEV2LOGREL(bounds.h);
- }
+ layoutOptions |= kATSLineNoAntiAliasing ;
}
- else
-#endif
+
+ 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 ++ )
{
- wxCharBuffer buff = text.mb_str(wxConvLocal);
- size_t len = strlen(buff);
- short* measurements = new short[len+1];
- MeasureText(len, buff.data(), measurements);
+ unsigned long actualNumberOfBounds = 0;
+ ATSTrapezoid glyphBounds;
- // Copy to widths, starting at measurements[1]
- // NOTE: this doesn't take into account any multi-byte characters
- // in buff, it probabkly should...
- for (size_t i=0; i<text.Length(); i++)
- widths[i] = XDEV2LOGREL(measurements[i + 1]);
+ // 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;
- delete [] measurements;
+ widths[pos] = XDEV2LOGREL(FixedToInt( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ));
}
+ ::ATSUDisposeTextLayout(atsuLayout);
+
return true;
}
wxCoord wxDC::GetCharWidth(void) const
{
- wxCHECK_MSG(Ok(), 1, wxT("wxDC::GetCharWidth - invalid DC"));
-
- wxMacFastPortSetter helper(this) ;
- int width = 0 ;
- const char text[] = "g" ;
-
- MacInstallFont() ;
-
-#if TARGET_CARBON
- bool useGetThemeText = ( GetThemeTextDimensions != (void*) kUnresolvedCFragSymbolAddress ) ;
- if ( UMAGetSystemVersion() < 0x1000 || ((wxFont*)&m_font)->GetNoAntiAliasing() )
- 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)
// if ( m_macFontInstalled )
// return ;
+
Pattern blackColor ;
MacSetupBackgroundForCurrentPort(m_backgroundBrush) ;
if ( m_backgroundMode != wxTRANSPARENT )
{
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[] =
//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
void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background )
{
Pattern whiteColor ;
+
if ( background.Ok() )
{
switch ( background.MacGetBrushKind() )
{
Rect extent ;
ThemeBackgroundKind bg = background.MacGetThemeBackground( &extent ) ;
- ::ApplyThemeBackground( bg , &extent ,kThemeStateActive , wxDisplayDepth() , true ) ;
+ ::ApplyThemeBackground( bg , &extent, kThemeStateActive , wxDisplayDepth() , true ) ;
}
break ;
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()) );
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())
{
for ( int i = 0 ; i < 8 ; ++i )
{
- pat.pat[i] = gwbits[i*alignment+0] ;
+ pat.pat[i] = gwbits[i * alignment + 0] ;
}
UnlockPixels( GetGWorldPixMap( gw ) ) ;
m_macFontInstalled = false ;
}
-// ---------------------------------------------------------------------------
-// coordinates transformations
-// ---------------------------------------------------------------------------
-
-wxCoord wxDCBase::DeviceToLogicalX(wxCoord x) const
-{
- return ((wxDC *)this)->XDEV2LOG(x);
-}
-
-wxCoord wxDCBase::DeviceToLogicalY(wxCoord y) const
-{
- return ((wxDC *)this)->YDEV2LOG(y);
-}
-
-wxCoord wxDCBase::DeviceToLogicalXRel(wxCoord x) const
-{
- return ((wxDC *)this)->XDEV2LOGREL(x);
-}
-
-wxCoord wxDCBase::DeviceToLogicalYRel(wxCoord y) const
-{
- return ((wxDC *)this)->YDEV2LOGREL(y);
-}
-
-wxCoord wxDCBase::LogicalToDeviceX(wxCoord x) const
-{
- return ((wxDC *)this)->XLOG2DEV(x);
-}
-
-wxCoord wxDCBase::LogicalToDeviceY(wxCoord y) const
-{
- return ((wxDC *)this)->YLOG2DEV(y);
-}
-
-wxCoord wxDCBase::LogicalToDeviceXRel(wxCoord x) const
-{
- return ((wxDC *)this)->XLOG2DEVREL(x);
-}
-
-wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
-{
- return ((wxDC *)this)->YLOG2DEVREL(y);
-}
-
#endif // !wxMAC_USE_CORE_GRAPHICS