virtual CGImageRef GetBitmap() { return m_bitmap; }
bool IsMonochrome() { return m_monochrome; }
+
+#if wxUSE_IMAGE
+ wxImage ConvertToImage() const
+ {
+ return wxBitmap(m_bitmap).ConvertToImage();
+ }
+#endif // wxUSE_IMAGE
+
private :
CGImageRef m_bitmap;
bool m_monochrome;
CGImageRelease( m_bitmap );
}
+
//
// Graphics Matrix
//
wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer);
- wxMacCoreGraphicsContext();
-
~wxMacCoreGraphicsContext();
void Init();
virtual bool SetAntialiasMode(wxAntialiasMode antialias);
+ virtual bool SetInterpolationQuality(wxInterpolationQuality interpolation);
+
virtual bool SetCompositionMode(wxCompositionMode op);
virtual void BeginLayer(wxDouble opacity);
virtual void DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h );
virtual void DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h );
+
+ // fast convenience methods
+
+
+ virtual void DrawRectangleX( wxDouble x, wxDouble y, wxDouble w, wxDouble h );
void SetNativeContext( CGContextRef cg );
- DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacCoreGraphicsContext)
+ wxDECLARE_NO_COPY_CLASS(wxMacCoreGraphicsContext);
private:
bool EnsureIsValid();
// wxMacCoreGraphicsContext implementation
//-----------------------------------------------------------------------------
-IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsContext, wxGraphicsContext)
-
class wxQuartzOffsetHelper
{
public :
m_view = NULL;
#endif
m_invisible = false;
+ m_antialias = wxANTIALIAS_DEFAULT;
+ m_interpolation = wxINTERPOLATION_DEFAULT;
}
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width, wxDouble height ) : wxGraphicsContext(renderer)
Init();
}
-wxMacCoreGraphicsContext::wxMacCoreGraphicsContext() : wxGraphicsContext(NULL)
-{
- Init();
- wxLogDebug(wxT("Illegal Constructor called"));
-}
-
wxMacCoreGraphicsContext::~wxMacCoreGraphicsContext()
{
SetNativeContext(NULL);
return true;
}
+bool wxMacCoreGraphicsContext::SetInterpolationQuality(wxInterpolationQuality interpolation)
+{
+ if (!EnsureIsValid())
+ return true;
+
+ if (m_interpolation == interpolation)
+ return true;
+
+ m_interpolation = interpolation;
+ CGInterpolationQuality quality;
+
+ switch (interpolation)
+ {
+ case wxINTERPOLATION_DEFAULT:
+ quality = kCGInterpolationDefault;
+ break;
+ case wxINTERPOLATION_NONE:
+ quality = kCGInterpolationNone;
+ break;
+ case wxINTERPOLATION_FAST:
+ quality = kCGInterpolationLow;
+ break;
+ case wxINTERPOLATION_GOOD:
+#if wxOSX_USE_COCOA_OR_CARBON
+ quality = UMAGetSystemVersion() < 0x1060 ? kCGInterpolationHigh : (CGInterpolationQuality) 4 /*kCGInterpolationMedium only on 10.6*/;
+#else
+ quality = kCGInterpolationMedium;
+#endif
+ break;
+ case wxINTERPOLATION_BEST:
+ quality = kCGInterpolationHigh;
+ break;
+ default:
+ return false;
+ }
+ CGContextSetInterpolationQuality(m_cgContext, quality);
+ return true;
+}
+
bool wxMacCoreGraphicsContext::SetCompositionMode(wxCompositionMode op)
{
if (!EnsureIsValid())
wxCFStringRef text(str, wxLocale::GetSystemEncoding() );
CTFontRef font = fref->OSXGetCTFont();
CGColorRef col = wxMacCreateCGColor( fref->GetColour() );
+#if 0
+ // right now there's no way to get continuous underlines, only words, so we emulate it
CTUnderlineStyle ustyle = fref->GetUnderlined() ? kCTUnderlineStyleSingle : kCTUnderlineStyleNone ;
wxCFRef<CFNumberRef> underlined( CFNumberCreate(NULL, kCFNumberSInt32Type, &ustyle) );
CFStringRef keys[] = { kCTFontAttributeName , kCTForegroundColorAttributeName, kCTUnderlineStyleAttributeName };
CFTypeRef values[] = { font, col, underlined };
+#else
+ CFStringRef keys[] = { kCTFontAttributeName , kCTForegroundColorAttributeName };
+ CFTypeRef values[] = { font, col };
+#endif
wxCFRef<CFDictionaryRef> attributes( CFDictionaryCreate(kCFAllocatorDefault, (const void**) &keys, (const void**) &values,
WXSIZEOF( keys ), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks) );
wxCFRef<CFAttributedStringRef> attrtext( CFAttributedStringCreate(kCFAllocatorDefault, text, attributes) );
CGContextScaleCTM(m_cgContext, 1, -1);
CGContextSetTextPosition(m_cgContext, 0, 0);
CTLineDraw( line, m_cgContext );
+
+ if ( fref->GetUnderlined() ) {
+ //AKT: draw horizontal line 1 pixel thick and with 1 pixel gap under baseline
+ CGFloat width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
+
+ CGPoint points[] = { {0.0, -2.0}, {width, -2.0} };
+
+ CGContextSetStrokeColorWithColor(m_cgContext, col);
+ CGContextSetShouldAntialias(m_cgContext, false);
+ CGContextSetLineWidth(m_cgContext, 1.0);
+ CGContextStrokeLineSegments(m_cgContext, points, 2);
+ }
+
CGContextRestoreGState(m_cgContext);
CFRelease( col );
return;
return m_cgContext;
}
+
+void wxMacCoreGraphicsContext::DrawRectangleX( wxDouble x, wxDouble y, wxDouble w, wxDouble h )
+{
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
+ CGRect rect = CGRectMake( (CGFloat) x , (CGFloat) y , (CGFloat) w , (CGFloat) h );
+ if ( !m_brush.IsNull() )
+ {
+ ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->Apply(this);
+ CGContextFillRect(m_cgContext, rect);
+ }
+
+ wxQuartzOffsetHelper helper( m_cgContext , ShouldOffset() );
+ if ( !m_pen.IsNull() )
+ {
+ ((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->Apply(this);
+ CGContextStrokeRect(m_cgContext, rect);
+ }
+}
+
// concatenates this transform with the current transform of this context
void wxMacCoreGraphicsContext::ConcatTransform( const wxGraphicsMatrix& matrix )
{
return m;
}
+
+#if wxUSE_IMAGE
+
+// ----------------------------------------------------------------------------
+// wxMacCoreGraphicsImageContext
+// ----------------------------------------------------------------------------
+
+// This is a GC that can be used to draw on wxImage. In this implementation we
+// simply draw on a wxBitmap using wxMemoryDC and then convert it to wxImage in
+// the end so it's not especially interesting and exists mainly for
+// compatibility with the other platforms.
+class wxMacCoreGraphicsImageContext : public wxMacCoreGraphicsContext
+{
+public:
+ wxMacCoreGraphicsImageContext(wxGraphicsRenderer* renderer,
+ wxImage& image) :
+ wxMacCoreGraphicsContext(renderer),
+ m_image(image),
+ m_bitmap(image),
+ m_memDC(m_bitmap)
+ {
+ SetNativeContext
+ (
+ (CGContextRef)(m_memDC.GetGraphicsContext()->GetNativeContext())
+ );
+ m_width = image.GetWidth();
+ m_height = image.GetHeight();
+ }
+
+ virtual ~wxMacCoreGraphicsImageContext()
+ {
+ m_memDC.SelectObject(wxNullBitmap);
+ m_image = m_bitmap.ConvertToImage();
+ }
+
+private:
+ wxImage& m_image;
+ wxBitmap m_bitmap;
+ wxMemoryDC m_memDC;
+};
+
+#endif // wxUSE_IMAGE
+
//
// Renderer
//
virtual wxGraphicsContext * CreateContext( wxWindow* window );
+#if wxUSE_IMAGE
+ virtual wxGraphicsContext * CreateContextFromImage(wxImage& image);
+#endif // wxUSE_IMAGE
+
virtual wxGraphicsContext * CreateMeasuringContext();
// Path
// sets the font
virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ;
+ virtual wxGraphicsFont CreateFont(double sizeInPixels,
+ const wxString& facename,
+ int flags = wxFONTFLAG_DEFAULT,
+ const wxColour& col = *wxBLACK);
// create a native bitmap representation
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) ;
+#if wxUSE_IMAGE
+ virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image);
+ virtual wxImage CreateImageFromBitmap(const wxGraphicsBitmap& bmp);
+#endif // wxUSE_IMAGE
+
// create a graphics bitmap from a native bitmap
virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap );
return new wxMacCoreGraphicsContext(this);
}
+#if wxUSE_IMAGE
+
+wxGraphicsContext*
+wxMacCoreGraphicsRenderer::CreateContextFromImage(wxImage& image)
+{
+ return new wxMacCoreGraphicsImageContext(this, image);
+}
+
+#endif // wxUSE_IMAGE
+
// Path
wxGraphicsPath wxMacCoreGraphicsRenderer::CreatePath()
return wxNullGraphicsBitmap;
}
+#if wxUSE_IMAGE
+
+wxGraphicsBitmap
+wxMacCoreGraphicsRenderer::CreateBitmapFromImage(const wxImage& image)
+{
+ // We don't have any direct way to convert wxImage to CGImage so pass by
+ // wxBitmap. This makes this function pretty useless in this implementation
+ // but it allows to have the same API as with Cairo backend where we can
+ // convert wxImage to a Cairo surface directly, bypassing wxBitmap.
+ return CreateBitmap(wxBitmap(image));
+}
+
+wxImage wxMacCoreGraphicsRenderer::CreateImageFromBitmap(const wxGraphicsBitmap& bmp)
+{
+ wxMacCoreGraphicsBitmapData* const
+ data = static_cast<wxMacCoreGraphicsBitmapData*>(bmp.GetRefData());
+
+ return data ? data->ConvertToImage() : wxNullImage;
+}
+
+#endif // wxUSE_IMAGE
+
wxGraphicsBitmap wxMacCoreGraphicsRenderer::CreateBitmapFromNativeBitmap( void* bitmap )
{
if ( bitmap != NULL )
return p;
}
-// sets the font
wxGraphicsFont wxMacCoreGraphicsRenderer::CreateFont( const wxFont &font , const wxColour &col )
{
if ( font.IsOk() )
return wxNullGraphicsFont;
}
+wxGraphicsFont
+wxMacCoreGraphicsRenderer::CreateFont(double sizeInPixels,
+ const wxString& facename,
+ int flags,
+ const wxColour& col)
+{
+ // This implementation is not ideal as we don't support fractional font
+ // sizes right now, but it's the simplest one.
+ //
+ // Notice that under Mac we always use 72 DPI so the font size in pixels is
+ // the same as the font size in points and we can pass it directly to wxFont
+ // ctor.
+ wxFont font(wxRound(sizeInPixels),
+ wxFONTFAMILY_DEFAULT,
+ flags & wxFONTFLAG_ITALIC ? wxFONTSTYLE_ITALIC
+ : wxFONTSTYLE_NORMAL,
+ flags & wxFONTFLAG_BOLD ? wxFONTWEIGHT_BOLD
+ : wxFONTWEIGHT_NORMAL,
+ (flags & wxFONTFLAG_UNDERLINED) != 0,
+ facename);
+
+ wxGraphicsFont f;
+ f.SetRefData(new wxMacCoreGraphicsFontData(this, font, col));
+ return f;
+}
+
//
// CoreGraphics Helper Methods
//