Example #1
0
        internal static CocoaContext GetCGContextForNSView(IntPtr handle)
        {
            if (handle == IntPtr.Zero)
            {
                return(null);
            }

            IntPtr focusView   = objc_msgSend(objc_getClass("NSView"), sel_registerName("focusView"));
            IntPtr focusHandle = IntPtr.Zero;

            if (focusView != handle)
            {
                if (!bool_objc_msgSend(handle, sel_registerName("lockFocusIfCanDraw")))
                {
                    return(null);
                }

                focusHandle = handle;
            }

            IntPtr windowHandle    = objc_msgSend(handle, sel_registerName("window"));
            IntPtr graphicsContext = objc_msgSend(windowHandle, sel_registerName("graphicsContext"));
            IntPtr ctx             = objc_msgSend(graphicsContext, sel_registerName("graphicsPort"));
            bool   isFlipped       = bool_objc_msgSend(handle, sel_registerName("isFlipped"));
            Size   size;

            CGContextSaveGState(ctx);

            if (IntPtr.Size == 4)
            {
                CGRect32 bounds = new CGRect32();
                objc_msgSend_stret(ref bounds, handle, sel_registerName("bounds"));
                if (isFlipped)
                {
                    CGContextTranslateCTM32(ctx, bounds.origin.x, bounds.size.height);
                    CGContextScaleCTM32(ctx, 1.0f, -1.0f);
                }
                size = new Size((int)bounds.size.width, (int)bounds.size.height);
            }
            else
            {
                CGRect64 bounds = new CGRect64();
                objc_msgSend_stret(ref bounds, handle, sel_registerName("bounds"));
                if (isFlipped)
                {
                    CGContextTranslateCTM64(ctx, bounds.origin.x, bounds.size.height);
                    CGContextScaleCTM64(ctx, 1.0f, -1.0f);
                }
                size = new Size((int)bounds.size.width, (int)bounds.size.height);
            }

            return(new CocoaContext(focusHandle, ctx, size.Width, size.Height));
        }
Example #2
0
 internal static extern void CGContextFillRect(IntPtr context, CGRect32 rect);
Example #3
0
 internal static extern void CGContextAddRect32(IntPtr context, CGRect32 rect);
Example #4
0
 internal static extern int HIViewConvertRect(ref CGRect32 r, IntPtr a, IntPtr b);
Example #5
0
 internal static extern int HIViewGetBounds(IntPtr vHnd, ref CGRect32 r);
Example #6
0
 public static extern void objc_msgSend_stret(ref CGRect32 arect, IntPtr basePtr, IntPtr selector);
Example #7
0
        internal static CarbonContext GetCGContextForView(IntPtr handle)
        {
            IntPtr context = IntPtr.Zero;
            IntPtr port    = IntPtr.Zero;
            IntPtr window  = IntPtr.Zero;

            if (IntPtr.Size == 8)
            {
                throw new NotSupportedException();
            }

            window = GetControlOwner(handle);

            if (handle == IntPtr.Zero || window == IntPtr.Zero)
            {
                // FIXME: Can we actually get a CGContextRef for the desktop?  this makes context IntPtr.Zero
                port = GetQDGlobalsThePort();
                CreateCGContextForPort(port, ref context);

                CGRect32 desktop_bounds = CGDisplayBounds32(CGMainDisplayID());

                return(new CarbonContext(port, context, (int)desktop_bounds.size.width, (int)desktop_bounds.size.height));
            }

            QDRect   window_bounds = new QDRect();
            CGRect32 view_bounds   = new CGRect32();

            port = GetWindowPort(window);

            context = GetContext(port);

            GetWindowBounds(window, 32, ref window_bounds);

            HIViewGetBounds(handle, ref view_bounds);

            HIViewConvertRect(ref view_bounds, handle, IntPtr.Zero);

            if (view_bounds.size.height < 0)
            {
                view_bounds.size.height = 0;
            }
            if (view_bounds.size.width < 0)
            {
                view_bounds.size.width = 0;
            }

            CGContextTranslateCTM32(context, view_bounds.origin.x, (window_bounds.bottom - window_bounds.top) - (view_bounds.origin.y + view_bounds.size.height));

            // Create the original rect path and clip to it
            CGRect32 rc_clip = new CGRect32(0, 0, view_bounds.size.width, view_bounds.size.height);

            CGContextSaveGState(context);

            Rectangle [] clip_rectangles = (Rectangle [])hwnd_delegate.DynamicInvoke(new object [] { handle });
            if (clip_rectangles != null && clip_rectangles.Length > 0)
            {
                int length = clip_rectangles.Length;

                CGContextBeginPath(context);
                CGContextAddRect32(context, rc_clip);

                for (int i = 0; i < length; i++)
                {
                    CGContextAddRect32(context, new CGRect32(clip_rectangles [i].X, view_bounds.size.height - clip_rectangles [i].Y - clip_rectangles [i].Height, clip_rectangles [i].Width, clip_rectangles [i].Height));
                }
                CGContextClosePath(context);
                CGContextEOClip(context);
#if DEBUG_CLIPPING
                if (clip_rectangles.Length >= debug_threshold)
                {
                    CGContextSetRGBFillColor(context, red, green, blue, 0.5f);
                    CGContextFillRect(context, rc_clip);
                    CGContextFlush(context);
                    System.Threading.Thread.Sleep(500);
                    if (red == 1.0f)
                    {
                        red = 0.0f; blue = 1.0f;
                    }
                    else if (blue == 1.0f)
                    {
                        blue = 0.0f; green = 1.0f;
                    }
                    else if (green == 1.0f)
                    {
                        green = 0.0f; red = 1.0f;
                    }
                }
#endif
            }
            else
            {
                CGContextBeginPath(context);
                CGContextAddRect32(context, rc_clip);
                CGContextClosePath(context);
                CGContextClip(context);
            }

            return(new CarbonContext(port, context, (int)view_bounds.size.width, (int)view_bounds.size.height));
        }