Exemple #1
0
        /// <summary>
        /// Draws a bitmap image.
        /// </summary>
        /// <param name="source">The bitmap image.</param>
        /// <param name="opacity">The opacity to draw with.</param>
        /// <param name="sourceRect">The rect in the image to draw.</param>
        /// <param name="destRect">The rect in the output to draw to.</param>
        public void DrawImage(IBitmapImpl bitmap, double opacity, Rect sourceRect, Rect destRect)
        {
            var pixbuf = bitmap as Gdk.Pixbuf;
            var rtb    = bitmap as RenderTargetBitmapImpl;
            var size   = new Size(pixbuf?.Width ?? rtb.PixelWidth, pixbuf?.Height ?? rtb.PixelHeight);
            var scale  = new Vector(destRect.Width / sourceRect.Width, destRect.Height / sourceRect.Height);

            _context.Save();
            _context.Scale(scale.X, scale.Y);
            destRect /= scale;

            _context.PushGroup();

            if (pixbuf != null)
            {
                Gdk.CairoHelper.SetSourcePixbuf(
                    _context,
                    pixbuf,
                    -sourceRect.X + destRect.X,
                    -sourceRect.Y + destRect.Y);
            }
            else
            {
                _context.SetSourceSurface(
                    rtb.Surface,
                    (int)(-sourceRect.X + destRect.X),
                    (int)(-sourceRect.Y + destRect.Y));
            }

            _context.Rectangle(destRect.ToCairo());
            _context.Fill();
            _context.PopGroupToSource();
            _context.PaintWithAlpha(opacityOverride);
            _context.Restore();
        }
Exemple #2
0
        void DrawPixbuf(Cairo.Context ctx, Gdk.Pixbuf img, double x, double y, ImageDescription idesc)
        {
            ctx.Save();
            ctx.Translate(x, y);
            ctx.Scale(idesc.Size.Width / (double)img.Width, idesc.Size.Height / (double)img.Height);
            Gdk.CairoHelper.SetSourcePixbuf(ctx, img, 0, 0);

                        #pragma warning disable 618
            using (var p = ctx.Source) {
                var pattern = p as Cairo.SurfacePattern;
                if (pattern != null)
                {
                    if (idesc.Size.Width > img.Width || idesc.Size.Height > img.Height)
                    {
                        // Fixes blur issue when rendering on an image surface
                        pattern.Filter = Cairo.Filter.Fast;
                    }
                    else
                    {
                        pattern.Filter = Cairo.Filter.Good;
                    }
                }
            }
                        #pragma warning restore 618

            if (idesc.Alpha >= 1)
            {
                ctx.Paint();
            }
            else
            {
                ctx.PaintWithAlpha(idesc.Alpha);
            }
            ctx.Restore();
        }
        void RenderIcon(Cairo.Context context, SurfaceWrapper surface, double opacity)
        {
            context.SetSourceSurface(surface.Surface,
                                     Allocation.X + (Allocation.Width - surface.Width) / 2,
                                     Allocation.Y + (Allocation.Height - surface.Height) / 2);

            context.PaintWithAlpha(opacity);
        }
Exemple #4
0
        public static Gdk.Pixbuf WithAlpha (this Gdk.Pixbuf image, double opacity)
        {
            using (var surf = new Cairo.ImageSurface (Cairo.Format.Argb32, image.Width, image.Height)) {
                using (var g = new Cairo.Context (surf)) {
                    CairoHelper.SetSourcePixbuf (g, image, 0, 0);
                    g.PaintWithAlpha (opacity);
                }

                return new Gdk.Pixbuf (surf.Data, true, 8, surf.Width, surf.Height, surf.Stride);
            }
        }
Exemple #5
0
        public static Gdk.Pixbuf WithAlpha(this Gdk.Pixbuf image, double opacity)
        {
            using (var surf = new Cairo.ImageSurface(Cairo.Format.Argb32, image.Width, image.Height)) {
                using (var g = new Cairo.Context(surf)) {
                    CairoHelper.SetSourcePixbuf(g, image, 0, 0);
                    g.PaintWithAlpha(opacity);
                }

                return(new Gdk.Pixbuf(surf.Data, true, 8, surf.Width, surf.Height, surf.Stride));
            }
        }
Exemple #6
0
        protected override void TileDrawer(int index, Cairo.Context cr)
        {
            int roomIndex = (Map.MainGroup << 8) | index;

            base.TileDrawer(index, cr);

            if (DarkenUsedDungeonRooms && Project.RoomUsedInDungeon(roomIndex))
            {
                cr.SetSourceRGB(0, 0, 0);
                cr.PaintWithAlpha(0.8);
            }
        }
Exemple #7
0
        /// <summary>
        /// Draws a bitmap image.
        /// </summary>
        /// <param name="source">The bitmap image.</param>
        /// <param name="opacity">The opacity to draw with.</param>
        /// <param name="sourceRect">The rect in the image to draw.</param>
        /// <param name="destRect">The rect in the output to draw to.</param>
        public void DrawImage(IBitmap bitmap, double opacity, Rect sourceRect, Rect destRect)
        {
            var impl  = bitmap.PlatformImpl as BitmapImpl;
            var size  = new Size(impl.PixelWidth, impl.PixelHeight);
            var scale = new Vector(destRect.Width / sourceRect.Width, destRect.Height / sourceRect.Height);

            _context.Save();
            _context.Scale(scale.X, scale.Y);
            destRect /= scale;

            if (opacityOverride < 1.0f)
            {
                _context.PushGroup();
                Gdk.CairoHelper.SetSourcePixbuf(
                    _context,
                    impl.Surface,
                    -sourceRect.X + destRect.X,
                    -sourceRect.Y + destRect.Y);

                _context.Rectangle(destRect.ToCairo());
                _context.Fill();
                _context.PopGroupToSource();
                _context.PaintWithAlpha(opacityOverride);
            }
            else
            {
                _context.PushGroup();
                Gdk.CairoHelper.SetSourcePixbuf(
                    _context,
                    impl.Surface,
                    -sourceRect.X + destRect.X,
                    -sourceRect.Y + destRect.Y);

                _context.Rectangle(destRect.ToCairo());
                _context.Fill();
                _context.PopGroupToSource();
                _context.PaintWithAlpha(opacityOverride);
            }
            _context.Restore();
        }
        // Used by the workspace drawing area expose render loop.
        // Takes care of the clipping.
        public void RenderLivePreviewLayer(Cairo.Context ctx, double opacity)
        {
            if (!IsEnabled)
            {
                throw new InvalidOperationException("Tried to render a live preview after live preview has ended.");
            }

            // TODO remove seam around selection during live preview.

            ctx.Save();
            if (selection_path != null)
            {
                // Paint area outsize of the selection path, with the pre-effect image.
                var imageSize = PintaCore.Workspace.ImageSize;
                ctx.Rectangle(0, 0, imageSize.Width, imageSize.Height);
                ctx.AppendPath(selection_path);
                ctx.Clip();
                ctx.SetSourceSurface(layer.Surface, (int)layer.Offset.X, (int)layer.Offset.Y);
                ctx.PaintWithAlpha(opacity);
                ctx.ResetClip();

                // Paint area inside the selection path, with the post-effect image.
                ctx.AppendPath(selection_path);
                ctx.Clip();

                ctx.SetSourceSurface(live_preview_surface, (int)layer.Offset.X, (int)layer.Offset.Y);
                ctx.PaintWithAlpha(opacity);

                ctx.AppendPath(selection_path);
                ctx.FillRule = Cairo.FillRule.EvenOdd;
                ctx.Clip();
            }
            else
            {
                ctx.SetSourceSurface(live_preview_surface, (int)layer.Offset.X, (int)layer.Offset.Y);
                ctx.PaintWithAlpha(opacity);
            }
            ctx.Restore();
        }
        private void UpdateThumbnail()
        {
            double scalex = (double)Allocation.Width / (double)PintaCore.Workspace.ImageSize.Width;
            double scaley = (double)Allocation.Height / (double)PintaCore.Workspace.ImageSize.Height;

            thumbnail = new Cairo.ImageSurface(Cairo.Format.Argb32, Allocation.Width, Allocation.Height);

            using (Cairo.Context g = new Cairo.Context(thumbnail)) {
                g.Scale(scalex, scaley);
                foreach (Layer layer in PintaCore.Layers.GetLayersToPaint())
                {
                    g.SetSourceSurface(layer.Surface, (int)layer.Offset.X, (int)layer.Offset.Y);
                    g.PaintWithAlpha(layer.Opacity);
                }
            }
        }
Exemple #10
0
 void DrawPixbuf(Cairo.Context ctx, Gdk.Pixbuf img, double x, double y, ImageDescription idesc)
 {
     ctx.Save();
     ctx.Translate(x, y);
     ctx.Scale(idesc.Size.Width / (double)img.Width, idesc.Size.Height / (double)img.Height);
     Gdk.CairoHelper.SetSourcePixbuf(ctx, img, 0, 0);
     if (idesc.Alpha == 1)
     {
         ctx.Paint();
     }
     else
     {
         ctx.PaintWithAlpha(idesc.Alpha);
     }
     ctx.Restore();
 }
        public void Fill(object backend)
        {
            var gtkc = (CairoContextBackend)backend;

            Cairo.Context ctx = gtkc.Context;
            if (gtkc.GlobalAlpha == 1)
            {
                ctx.Fill();
            }
            else
            {
                ctx.PushGroup();
                ctx.Fill();
                ctx.PopGroupToSource();
                ctx.PaintWithAlpha(gtkc.GlobalAlpha);
            }
        }
Exemple #12
0
            protected override void TileDrawer(int index, Cairo.Context cr)
            {
                base.TileDrawer(index, cr);

                int x = index % Width;
                int y = index / Width;

                cr.Save();
                if (GetSelected(x, y))
                {
                    cr.SetSourceRGB(1.0, 0, 0);
                    //cr.Rectangle(0, 0, TileWidth, TileHeight);
                    cr.PaintWithAlpha(0.4);

                    CairoHelper.DrawRectOutline(cr, 1, new Cairo.Rectangle(0, 0, TileWidth, TileHeight));
                }
                cr.Restore();
            }
        /// TODO: CairoExtensions.CachedDraw seems not to work correctly for me.
        public static void CachedDraw(Cairo.Context self, ref SurfaceWrapper surface, Gdk.Rectangle region, object parameters = null, float opacity = 1.0f, Action <Cairo.Context, float> draw = null, double?forceScale = null)
        {
            double displayScale = forceScale.HasValue ? forceScale.Value : QuartzSurface.GetRetinaScale(self);
            int    targetWidth  = (int)(region.Width * displayScale);
            int    targetHeight = (int)(region.Height * displayScale);

            bool redraw = false;

            if (surface == null || surface.Width != targetWidth || surface.Height != targetHeight)
            {
                if (surface != null)
                {
                    surface.Dispose();
                }
                surface = new SurfaceWrapper(self, targetWidth, targetHeight);
                redraw  = true;
            }
            else if ((surface.Data == null && parameters != null) || (surface.Data != null && !surface.Data.Equals(parameters)))
            {
                redraw = true;
            }


            if (redraw)
            {
                surface.Data = parameters;
                using (var context = new Cairo.Context(surface.Surface)) {
                    context.Operator = Cairo.Operator.Clear;
                    context.Paint();
                    context.Operator = Cairo.Operator.Over;
                    context.Save();
                    context.Scale(displayScale, displayScale);
                    draw(context, 1.0f);
                    context.Restore();
                }
            }

            self.Save();
            self.Translate(region.X, region.Y);
            self.Scale(1 / displayScale, 1 / displayScale);
            self.SetSourceSurface(surface.Surface, 0, 0);
            self.PaintWithAlpha(opacity);
            self.Restore();
        }
Exemple #14
0
        public override void FillPreserve(object backend)
        {
            var gtkc = (CairoContextBackend)backend;

            Cairo.Context ctx   = gtkc.Context;
            var           alpha = gtkc.GlobalAlpha * gtkc.PatternAlpha;

            if (alpha == 1)
            {
                ctx.FillPreserve();
            }
            else
            {
                ctx.Save();
                ctx.ClipPreserve();
                ctx.PaintWithAlpha(alpha);
                ctx.Restore();
            }
        }
Exemple #15
0
        public virtual void Render(Cairo.Context cr)
        {
            double opacity = Opacity;

            if (ContentAllocation.Width <= 0 || ContentAllocation.Height <= 0 || opacity <= 0)
            {
                return;
            }

            cr.Save();

            if (opacity < 1.0)
            {
                cr.PushGroup();
            }

            MarginStyle margin_style = MarginStyle;

            if (margin_style != null && margin_style != MarginStyle.None)
            {
                cr.Translate(Math.Round(Allocation.X), Math.Round(Allocation.Y));
                cr.Save();
                margin_style.Apply(this, cr);
                cr.Restore();
                cr.Translate(Math.Round(Margin.Left), Math.Round(Margin.Top));
            }
            else
            {
                cr.Translate(Math.Round(ContentAllocation.X), Math.Round(ContentAllocation.Y));
            }

            cr.Antialias = Cairo.Antialias.Default;
            ClippedRender(cr);

            if (opacity < 1.0)
            {
                cr.PopGroupToSource();
                cr.PaintWithAlpha(Opacity);
            }

            cr.Restore();
        }
Exemple #16
0
        private static void MakeReflection(Cairo.Context context, Cairo.ImageSurface source, int w, int h)
        {
            context.ResetClip();
            context.SetSourceSurface(source, 2, 2);
            context.Paint();

            double alpha = -0.3;
            double step  = 1.0 / (double)source.Height;

            context.Translate(0, h);
            context.Scale(1, -1);
            context.SetSourceSurface(source, 2, 2);
            for (int i = 0; i < source.Height; i++)
            {
                context.Rectangle(0, i + 2, w, 1);
                context.Clip();
                alpha += step;
                context.PaintWithAlpha(Math.Max(Math.Min(alpha, 0.7), 0.0));
                context.ResetClip();
            }
        }
Exemple #17
0
        protected override bool OnExposeEvent(EventExpose e)
        {
            base.OnExposeEvent(e);

            if (!PintaCore.Workspace.HasOpenDocuments)
            {
                return(true);
            }

            double scale = PintaCore.Workspace.Scale;

            int x = (int)PintaCore.Workspace.Offset.X;
            int y = (int)PintaCore.Workspace.Offset.Y;

            // Translate our expose area for the whole drawingarea to just our canvas
            Rectangle canvas_bounds = new Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width, PintaCore.Workspace.CanvasSize.Height);

            canvas_bounds.Intersect(e.Area);

            if (canvas_bounds.IsEmpty)
            {
                return(true);
            }

            canvas_bounds.X -= x;
            canvas_bounds.Y -= y;

            // Resize our offscreen surface to a surface the size of our drawing area
            if (canvas == null || canvas.Width != canvas_bounds.Width || canvas.Height != canvas_bounds.Height)
            {
                if (canvas != null)
                {
                    (canvas as IDisposable).Dispose();
                }

                canvas = new Cairo.ImageSurface(Cairo.Format.Argb32, canvas_bounds.Width, canvas_bounds.Height);
            }

            cr.Initialize(PintaCore.Workspace.ImageSize, PintaCore.Workspace.CanvasSize);

            using (Cairo.Context g = CairoHelper.Create(GdkWindow)) {
                // Draw our 1 px black border
                g.DrawRectangle(new Cairo.Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width + 1, PintaCore.Workspace.CanvasSize.Height + 1), new Cairo.Color(0, 0, 0), 1);

                // Set up our clip rectangle
                g.Rectangle(new Cairo.Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width, PintaCore.Workspace.CanvasSize.Height));
                g.Clip();

                g.Translate(x, y);

                bool checker = true;

                // Resize each layer and paint it to the screen
                foreach (Layer layer in PintaCore.Layers.GetLayersToPaint())
                {
                    cr.Render(layer.Surface, canvas, canvas_bounds.Location, checker);
                    g.SetSourceSurface(canvas, canvas_bounds.X + (int)(layer.Offset.X * scale), canvas_bounds.Y + (int)(layer.Offset.Y * scale));
                    g.PaintWithAlpha(layer.Opacity);

                    if (layer == PintaCore.Layers.CurrentLayer && PintaCore.LivePreview.IsEnabled)
                    {
                        cr.Render(PintaCore.LivePreview.LivePreviewSurface, canvas, canvas_bounds.Location, checker);

                        g.Save();
                        g.Scale(scale, scale);
                        g.AppendPath(PintaCore.Layers.SelectionPath);
                        g.Clip();

                        g.Scale(1 / scale, 1 / scale);
                        g.SetSourceSurface(canvas, canvas_bounds.X, canvas_bounds.Y);
                        g.PaintWithAlpha(layer.Opacity);

                        g.Restore();
                    }

                    checker = false;
                }

                // If we are at least 200% and grid is requested, draw it
                if (PintaCore.Actions.View.PixelGrid.Active && cr.ScaleFactor.Ratio <= 0.5d)
                {
                    gr.Render(canvas, canvas_bounds.Location);
                    g.SetSourceSurface(canvas, canvas_bounds.X, canvas_bounds.Y);
                    g.Paint();
                }

                // Selection outline
                if (PintaCore.Layers.ShowSelection)
                {
                    g.Save();
                    g.Translate(0.5, 0.5);
                    g.Scale(scale, scale);

                    g.AppendPath(PintaCore.Layers.SelectionPath);

                    if (PintaCore.Tools.CurrentTool.Name.Contains("Select") && !PintaCore.Tools.CurrentTool.Name.Contains("Selected"))
                    {
                        g.Color    = new Cairo.Color(0.7, 0.8, 0.9, 0.2);
                        g.FillRule = Cairo.FillRule.EvenOdd;
                        g.FillPreserve();
                    }

                    g.LineWidth = 1 / scale;

                    // Draw a white line first so it shows up on dark backgrounds
                    g.Color = new Cairo.Color(1, 1, 1);
                    g.StrokePreserve();

                    // Draw a black dashed line over the white line
                    g.SetDash(new double[] { 2 / scale, 4 / scale }, 0);
                    g.Color = new Cairo.Color(0, 0, 0);

                    g.Stroke();
                    g.Restore();
                }
            }

            return(true);
        }
Exemple #18
0
        private void UpdateThumbnail()
        {
            double scalex = (double)Allocation.Width / (double)PintaCore.Workspace.ImageSize.Width;
            double scaley = (double)Allocation.Height / (double)PintaCore.Workspace.ImageSize.Height;

            thumbnail = new Cairo.ImageSurface (Cairo.Format.Argb32, Allocation.Width, Allocation.Height);

            using (Cairo.Context g = new Cairo.Context (thumbnail)) {
                g.Scale (scalex, scaley);
                foreach (Layer layer in PintaCore.Layers.GetLayersToPaint ()) {
                    g.SetSourceSurface (layer.Surface, (int)layer.Offset.X, (int)layer.Offset.Y);
                    g.PaintWithAlpha (layer.Opacity);
                }
            }
        }