diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index 40ff9d38d9..93ee03514d 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -501,20 +501,15 @@ void wxGCDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h, if ( !m_logicalFunctionSupported ) return; - bool fill = m_brush.GetStyle() != wxTRANSPARENT; - wxGraphicsPath path = m_graphicContext->CreatePath(); m_graphicContext->PushState(); - m_graphicContext->Translate(x+w/2,y+h/2); + m_graphicContext->Translate(x+w/2.0,y+h/2.0); wxDouble factor = ((wxDouble) w) / h; m_graphicContext->Scale( factor , 1.0); - if ( fill && (sa!=ea) ) - path.MoveToPoint(0,0); + // since these angles (ea,sa) are measured counter-clockwise, we invert them to // get clockwise angles - path.AddArc( 0, 0, h/2 , DegToRad(-sa) , DegToRad(-ea), sa > ea ); - if ( fill && (sa!=ea) ) - path.AddLineToPoint(0,0); + path.AddArc( 0, 0, h/2.0 , DegToRad(-sa) , DegToRad(-ea), sa > ea ); m_graphicContext->DrawPath( path ); m_graphicContext->PopState(); } @@ -698,6 +693,13 @@ void wxGCDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, if (w == 0 || h == 0) return; + if ( m_graphicContext->ShouldOffset() ) + { + // if we are offsetting the entire rectangle is moved 0.5, so the + // border line gets off by 1 + w -= 1; + h -= 1; + } m_graphicContext->DrawRoundedRectangle( x,y,w,h,radius); } @@ -708,6 +710,13 @@ void wxGCDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord w, wxCoord h) if ( !m_logicalFunctionSupported ) return; + if ( m_graphicContext->ShouldOffset() ) + { + // if we are offsetting the entire rectangle is moved 0.5, so the + // border line gets off by 1 + w -= 1; + h -= 1; + } m_graphicContext->DrawEllipse(x,y,w,h); } diff --git a/src/common/sizer.cpp b/src/common/sizer.cpp index 0fc04d7c37..66a1525431 100644 --- a/src/common/sizer.cpp +++ b/src/common/sizer.cpp @@ -2022,7 +2022,8 @@ void wxStdDialogButtonSizer::Realize() if (m_buttonAffirmative->GetId() == wxID_SAVE){ // these buttons have set labels under Mac so we should use them m_buttonAffirmative->SetLabel(_("Save")); - m_buttonNegative->SetLabel(_("Don't Save")); + if (m_buttonNegative) + m_buttonNegative->SetLabel(_("Don't Save")); } } diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index 7ab1b5cdaf..f40b1c5845 100755 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -37,6 +37,7 @@ #endif #include "wx/graphics.h" +#include "wx/rawbmp.h" #if wxUSE_GRAPHICS_CONTEXT @@ -757,7 +758,9 @@ void wxCairoPathData::AddLineToPoint( wxDouble x , wxDouble y ) void wxCairoPathData::AddPath( const wxGraphicsPathData* path ) { - // TODO + cairo_path_t* p = (cairo_path_t*)path->GetNativePath(); + cairo_append_path(m_pathContext, p); + UnGetNativePath(p); } void wxCairoPathData::CloseSubpath() @@ -1028,19 +1031,44 @@ wxCairoContext::~wxCairoContext() } -void wxCairoContext::Clip( const wxRegion & WXUNUSED(region) ) +void wxCairoContext::Clip( const wxRegion& region ) { -// TODO + // Create a path with all the rectangles in the region + wxGraphicsPath path = GetRenderer()->CreatePath(); + wxRegionIterator ri(region); + while (ri) + { + path.AddRectangle(ri.GetX(), ri.GetY(), ri.GetW(), ri.GetH()); + ri++; + } + + // Put it in the context + cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ; + cairo_append_path(m_context, cp); + + // clip to that path + cairo_clip(m_context); + path.UnGetNativePath(cp); } void wxCairoContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { -// TODO + // Create a path with this rectangle + wxGraphicsPath path = GetRenderer()->CreatePath(); + path.AddRectangle(x,y,w,h); + + // Put it in the context + cairo_path_t* cp = (cairo_path_t*) path.GetNativePath() ; + cairo_append_path(m_context, cp); + + // clip to that path + cairo_clip(m_context); + path.UnGetNativePath(cp); } void wxCairoContext::ResetClip() { -// TODO + cairo_reset_clip(m_context); } @@ -1118,37 +1146,156 @@ void wxCairoContext::PopState() void wxCairoContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { - /* - Bitmap* image = Bitmap::FromHBITMAP((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE()); - m_context->DrawImage(image,(REAL) x,(REAL) y,(REAL) w,(REAL) h) ; - delete image ; - */ + wxCHECK_RET( bmp.IsOk(), wxT("Invalid bitmap in wxCairoContext::DrawBitmap")); + + cairo_surface_t* surface; + int bw = bmp.GetWidth(); + int bh = bmp.GetHeight(); + wxBitmap bmpSource = bmp; // we need a non-const instance + unsigned char* buffer = new unsigned char[bw*bh*4]; + wxUint32* data = (wxUint32*)buffer; + + // Create a surface object and copy the bitmap pixel data to it. if the + // image has alpha (or a mask represented as alpha) then we'll use a + // different format and iterator than if it doesn't... + if (bmpSource.HasAlpha() || bmpSource.GetMask()) + { + surface = cairo_image_surface_create_for_data( + buffer, CAIRO_FORMAT_ARGB32, bw, bh, bw*4); + wxAlphaPixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh)); + wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data.")); + + wxAlphaPixelData::Iterator p(pixData); + for (int y=0; yDrawImage(image,(REAL) x,(REAL) y,(REAL) w,(REAL) h) ; - delete image ; - */ + // An icon is a bitmap on wxGTK, so do this the easy way. When we want to + // start using the Cairo backend on other platforms then we may need to + // fiddle with this... + DrawBitmap(icon, x, y, w, h); } void wxCairoContext::DrawText( const wxString &str, wxDouble x, wxDouble y ) { - if ( m_font.IsNull() || str.IsEmpty()) - return ; - cairo_move_to(m_context,x,y); - const wxWX2MBbuf buf(str.mb_str(wxConvUTF8)); + if ( m_font.IsNull() || str.empty()) + return; + ((wxCairoFontData*)m_font.GetRefData())->Apply(this); + + // Cairo's x,y for drawing text is at the baseline, so we need to adjust + // the position we move to by the ascent. + cairo_font_extents_t fe; + cairo_font_extents(m_context, &fe); + cairo_move_to(m_context, x, y+fe.ascent); + + const wxWX2MBbuf buf(str.mb_str(wxConvUTF8)); cairo_show_text(m_context,buf); } void wxCairoContext::GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height, wxDouble *descent, wxDouble *externalLeading ) const { - // TODO + if ( m_font.IsNull() || str.empty()) + return; + + ((wxCairoFontData*)m_font.GetRefData())->Apply((wxCairoContext*)this); + + if (width) + { + const wxWX2MBbuf buf(str.mb_str(wxConvUTF8)); + cairo_text_extents_t te; + cairo_text_extents(m_context, buf, &te); + *width = te.width; + } + + if (height || descent || externalLeading) + { + cairo_font_extents_t fe; + cairo_font_extents(m_context, &fe); + + if (height) + *height = fe.height; + if ( descent ) + *descent = fe.descent; + if ( externalLeading ) + *externalLeading = wxMax(0, fe.height - (fe.ascent + fe.descent)); + } } void wxCairoContext::GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const diff --git a/src/mac/carbon/font.cpp b/src/mac/carbon/font.cpp index 77a08d7855..fe8a315e25 100644 --- a/src/mac/carbon/font.cpp +++ b/src/mac/carbon/font.cpp @@ -254,6 +254,7 @@ void wxFontRefData::MacFindFont() break ; case wxMODERN : + case wxTELETYPE: m_faceName = wxT("Monaco"); break ; diff --git a/src/mac/carbon/graphics.cpp b/src/mac/carbon/graphics.cpp index 0a22635202..b2bcb0788a 100755 --- a/src/mac/carbon/graphics.cpp +++ b/src/mac/carbon/graphics.cpp @@ -17,6 +17,7 @@ #ifndef WX_PRECOMP #include "wx/dcclient.h" + #include "wx/dcmemory.h" #include "wx/log.h" #include "wx/region.h" #endif @@ -2013,7 +2014,16 @@ wxGraphicsRenderer* wxGraphicsRenderer::GetDefaultRenderer() wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc) { - return new wxMacCoreGraphicsContext(this,(CGContextRef)dc.GetWindow()->MacGetCGContextRef() ); + wxMemoryDC* mdc = wxDynamicCast(&dc, wxMemoryDC); + if ( mdc ) + { + return new wxMacCoreGraphicsContext(this, + (CGContextRef)mdc->GetGraphicsContext()->GetNativeContext()); + } + else + { + return new wxMacCoreGraphicsContext(this,(CGContextRef)dc.GetWindow()->MacGetCGContextRef() ); + } } wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContextFromNativeContext( void * context ) diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index 142c2f60e8..bda43979a7 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -303,6 +303,7 @@ public: virtual void GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height, wxDouble *descent, wxDouble *externalLeading ) const; virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const; + virtual bool ShouldOffset() const; private: void Init(); @@ -1185,6 +1186,18 @@ void wxGDIPlusContext::GetPartialTextExtents(const wxString& text, wxArrayDouble } } +bool wxGDIPlusContext::ShouldOffset() const +{ + int penwidth = 0 ; + if ( !m_pen.IsNull() ) + { + penwidth = (int)((wxGDIPlusPenData*)m_pen.GetRefData())->GetWidth(); + if ( penwidth == 0 ) + penwidth = 1; + } + return ( penwidth % 2 ) == 1; +} + void* wxGDIPlusContext::GetNativeContext() { return m_context;