示例#1
0
        public virtual void Crop(Gdk.Rectangle rect, Path?selection)
        {
            ImageSurface dest = CairoExtensions.CreateImageSurface(Format.Argb32, rect.Width, rect.Height);



            using (Context g = new Context(dest)) {
                // Move the selected content to the upper left
                g.Translate(-rect.X, -rect.Y);
                g.Antialias = Antialias.None;

                // Optionally, respect the given path.
                if (selection != null)
                {
                    g.AppendPath(selection);
                    g.FillRule = Cairo.FillRule.EvenOdd;
                    g.Clip();
                }

                g.SetSource(Surface);
                g.Paint();
            }

            (Surface as IDisposable).Dispose();
            Surface = dest;
        }
示例#2
0
        private void HandlerPintaCoreActionsEditCopyActivated(object sender, EventArgs e)
        {
            Document doc = PintaCore.Workspace.ActiveDocument;

            Gtk.Clipboard cb = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
            if (PintaCore.Tools.CurrentTool?.DoHandleCopy(doc, cb) == true)
            {
                return;
            }

            PintaCore.Tools.Commit();

            using (ImageSurface src = doc.Layers.GetClippedLayer(doc.Layers.CurrentUserLayerIndex)) {
                Gdk.Rectangle rect = doc.GetSelectedBounds(true);
                if (rect.Width == 0 || rect.Height == 0)
                {
                    return;
                }

                ImageSurface dest = CairoExtensions.CreateImageSurface(Format.Argb32, rect.Width, rect.Height);

                using (Context g = new Context(dest)) {
                    g.SetSourceSurface(src, -rect.X, -rect.Y);
                    g.Paint();
                }

                cb.Image = dest.ToPixbuf();

                (dest as IDisposable).Dispose();
            }
        }
示例#3
0
 public static Pixbuf CreateColorSwatch(int size, Color color)
 {
     using (var surf = CairoExtensions.CreateImageSurface(Cairo.Format.Argb32, size, size))
         using (var g = new Cairo.Context(surf)) {
             g.FillRectangle(new Cairo.Rectangle(0, 0, size, size), color.ToCairoColor());
             g.DrawRectangle(new Cairo.Rectangle(0, 0, size, size), new Cairo.Color(0, 0, 0), 1);
             return(surf.ToPixbuf());
         }
 }
示例#4
0
        /// <summary>
        /// Setup the Layer based on the parent UserLayer's Surface.
        /// </summary>
        private void SetupLayer()
        {
            var surface = CairoExtensions.CreateImageSurface(parent.Surface.Format, parent.Surface.Width, parent.Surface.Height);

            actualLayer = new Layer(surface);


            isLayerSetup = true;
        }
示例#5
0
        public static Cairo.Surface ToSurface(this Pixbuf pixbuf)
        {
            var surface = CairoExtensions.CreateImageSurface(Cairo.Format.ARGB32, pixbuf.Width, pixbuf.Height);

            using (var g = new Cairo.Context(surface)) {
                Gdk.CairoHelper.SetSourcePixbuf(g, pixbuf, 0, 0);
                g.Paint();
            }

            return(surface);
        }
示例#6
0
        public virtual void ResizeCanvas(int width, int height, Anchor anchor)
        {
            ImageSurface dest = CairoExtensions.CreateImageSurface(Format.Argb32, width, height);

            int delta_x = Surface.Width - width;
            int delta_y = Surface.Height - height;

            using (Context g = new Context(dest)) {
                switch (anchor)
                {
                case Anchor.NW:
                    g.SetSourceSurface(Surface, 0, 0);
                    break;

                case Anchor.N:
                    g.SetSourceSurface(Surface, -delta_x / 2, 0);
                    break;

                case Anchor.NE:
                    g.SetSourceSurface(Surface, -delta_x, 0);
                    break;

                case Anchor.E:
                    g.SetSourceSurface(Surface, -delta_x, -delta_y / 2);
                    break;

                case Anchor.SE:
                    g.SetSourceSurface(Surface, -delta_x, -delta_y);
                    break;

                case Anchor.S:
                    g.SetSourceSurface(Surface, -delta_x / 2, -delta_y);
                    break;

                case Anchor.SW:
                    g.SetSourceSurface(Surface, 0, -delta_y);
                    break;

                case Anchor.W:
                    g.SetSourceSurface(Surface, 0, -delta_y / 2);
                    break;

                case Anchor.Center:
                    g.SetSourceSurface(Surface, -delta_x / 2, -delta_y / 2);
                    break;
                }

                g.Paint();
            }

            (Surface as IDisposable).Dispose();
            Surface = dest;
        }
示例#7
0
        public virtual void ApplyTransform(Matrix xform, Size new_size)
        {
            var old_size = PintaCore.Workspace.ImageSize;
            var dest     = CairoExtensions.CreateImageSurface(Format.ARGB32, new_size.Width, new_size.Height);

            using (var g = new Context(dest)) {
                g.Transform(xform);
                g.SetSource(Surface);
                g.Paint();
            }

            Surface old = Surface;

            Surface = dest;
            old.Dispose();
        }
示例#8
0
        public virtual void Resize(int width, int height)
        {
            ImageSurface dest = CairoExtensions.CreateImageSurface(Format.Argb32, width, height);

            Pixbuf pb       = Surface.ToPixbuf();
            Pixbuf pbScaled = pb.ScaleSimple(width, height, InterpType.Bilinear);

            using (Context g = new Context(dest)) {
                CairoHelper.SetSourcePixbuf(g, pbScaled, 0, 0);
                g.Paint();
            }

            (Surface as IDisposable).Dispose();
            (pb as IDisposable).Dispose();
            (pbScaled as IDisposable).Dispose();
            Surface = dest;
        }
示例#9
0
        /// <summary>
        /// Gets the final pixel color for the given point, taking layers, opacity, and blend modes into account.
        /// </summary>
        public ColorBgra GetComputedPixel(int x, int y)
        {
            using (var dst = CairoExtensions.CreateImageSurface(Format.Argb32, 1, 1)) {
                using (var g = new Context(dst)) {
                    foreach (var layer in Layers.GetLayersToPaint())
                    {
                        var color = layer.Surface.GetColorBgraUnchecked(x, y).ToStraightAlpha().ToCairoColor();

                        g.SetBlendMode(layer.BlendMode);
                        g.SetSourceColor(color);

                        g.Rectangle(dst.GetBounds().ToCairoRectangle());
                        g.PaintWithAlpha(layer.Opacity);
                    }
                }

                return(dst.GetColorBgraUnchecked(0, 0));
            }
        }
示例#10
0
        private void HandlerPintaCoreActionsEditCopyMergedActivated(object sender, EventArgs e)
        {
            var cb  = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
            var doc = PintaCore.Workspace.ActiveDocument;

            PintaCore.Tools.Commit();

            // Get our merged ("flattened") image
            using (var src = doc.GetFlattenedImage(/* clip_to_selection */ true)) {
                var rect = doc.GetSelectedBounds(true);

                // Copy it to a correctly sized surface
                using (var dest = CairoExtensions.CreateImageSurface(Format.Argb32, rect.Width, rect.Height)) {
                    using (Context g = new Context(dest)) {
                        g.SetSourceSurface(src, -rect.X, -rect.Y);
                        g.Paint();
                    }

                    // Give it to the clipboard
                    cb.Image = dest.ToPixbuf();
                }
            }
        }
示例#11
0
        /// <summary>
        /// Create a cursor icon with a shape that visually represents the tool's thickness.
        /// </summary>
        /// <param name="imgName">A string containing the name of the tool's icon image to use.</param>
        /// <param name="shape">The shape to draw.</param>
        /// <param name="shapeWidth">The width of the shape.</param>
        /// <param name="imgToShapeX">The horizontal distance between the image's top-left corner and the shape center.</param>
        /// <param name="imgToShapeY">The verical distance between the image's top-left corner and the shape center.</param>
        /// <param name="shapeX">The X position in the returned Pixbuf that will be the center of the shape.</param>
        /// <param name="shapeY">The Y position in the returned Pixbuf that will be the center of the shape.</param>
        /// <returns>The new cursor icon with an shape that represents the tool's thickness.</returns>
        public static Gdk.Pixbuf CreateIconWithShape(string imgName, CursorShape shape, int shapeWidth,
                                                     int imgToShapeX, int imgToShapeY,
                                                     out int shapeX, out int shapeY)
        {
            Gdk.Pixbuf img = PintaCore.Resources.GetIcon(imgName);

            double zoom = 1d;

            if (PintaCore.Workspace.HasOpenDocuments)
            {
                zoom = Math.Min(30d, PintaCore.Workspace.ActiveDocument.Workspace.Scale);
            }

            shapeWidth = (int)Math.Min(800d, ((double)shapeWidth) * zoom);
            int halfOfShapeWidth = shapeWidth / 2;

            // Calculate bounding boxes around the both image and shape
            // relative to the image top-left corner.
            Gdk.Rectangle imgBBox   = new Gdk.Rectangle(0, 0, img.Width, img.Height);
            Gdk.Rectangle shapeBBox = new Gdk.Rectangle(
                imgToShapeX - halfOfShapeWidth,
                imgToShapeY - halfOfShapeWidth,
                shapeWidth,
                shapeWidth);

            // Inflate shape bounding box to allow for anti-aliasing
            shapeBBox.Inflate(2, 2);

            // To determine required size of icon,
            // find union of the image and shape bounding boxes
            // (still relative to image top-left corner)
            Gdk.Rectangle iconBBox = imgBBox.Union(shapeBBox);

            // Image top-left corner in icon co-ordinates
            int imgX = imgBBox.Left - iconBBox.Left;
            int imgY = imgBBox.Top - iconBBox.Top;

            // Shape center point in icon co-ordinates
            shapeX = imgToShapeX - iconBBox.Left;
            shapeY = imgToShapeY - iconBBox.Top;

            using (var i = CairoExtensions.CreateImageSurface(Cairo.Format.ARGB32, iconBBox.Width, iconBBox.Height)) {
                using (var g = new Cairo.Context(i)) {
                    // Don't show shape if shapeWidth less than 3,
                    if (shapeWidth > 3)
                    {
                        int             diam      = Math.Max(1, shapeWidth - 2);
                        Cairo.Rectangle shapeRect = new Cairo.Rectangle(shapeX - halfOfShapeWidth,
                                                                        shapeY - halfOfShapeWidth,
                                                                        diam,
                                                                        diam);

                        Cairo.Color outerColor = new Cairo.Color(255, 255, 255, 0.75);
                        Cairo.Color innerColor = new Cairo.Color(0, 0, 0);

                        switch (shape)
                        {
                        case CursorShape.Ellipse:
                            g.DrawEllipse(shapeRect, outerColor, 2);
                            shapeRect = shapeRect.Inflate(-1, -1);
                            g.DrawEllipse(shapeRect, innerColor, 1);
                            break;

                        case CursorShape.Rectangle:
                            g.DrawRectangle(shapeRect, outerColor, 1);
                            shapeRect = shapeRect.Inflate(-1, -1);
                            g.DrawRectangle(shapeRect, innerColor, 1);
                            break;
                        }
                    }

                    // Draw the image
                    g.DrawPixbuf(img, new Cairo.Point(imgX, imgY));
                }

                return(CairoExtensions.ToPixbuf(i));
            }
        }
示例#12
0
        public void Start(BaseEffect effect)
        {
            if (live_preview_enabled)
            {
                throw new InvalidOperationException("LivePreviewManager.Start() called while live preview is already enabled.");
            }

            // Create live preview surface.
            // Start rendering.
            // Listen for changes to effectConfiguration object, and restart render if needed.

            var doc = PintaCore.Workspace.ActiveDocument;

            live_preview_enabled     = true;
            apply_live_preview_flag  = false;
            cancel_live_preview_flag = false;

            layer       = doc.Layers.CurrentUserLayer;
            this.effect = effect;

            //TODO Use the current tool layer instead.
            live_preview_surface = CairoExtensions.CreateImageSurface(Cairo.Format.Argb32,
                                                                      PintaCore.Workspace.ImageSize.Width,
                                                                      PintaCore.Workspace.ImageSize.Height);

            // Handle selection path.
            PintaCore.Tools.Commit();
            var selection = doc.Selection;

            selection_path = (selection.Visible) ? selection.SelectionPath : null;
            render_bounds  = (selection_path != null) ? selection_path.GetBounds() : live_preview_surface.GetBounds();
            render_bounds  = PintaCore.Workspace.ClampToImageSize(render_bounds);

            history_item = new SimpleHistoryItem(effect.Icon, effect.Name);
            history_item.TakeSnapshotOfLayer(doc.Layers.CurrentUserLayerIndex);

            // Paint the pre-effect layer surface into into the working surface.
            using (var ctx = new Cairo.Context(live_preview_surface)) {
                layer.Draw(ctx, layer.Surface, 1);
            }

            if (effect.EffectData != null)
            {
                effect.EffectData.PropertyChanged += EffectData_PropertyChanged;
            }

            if (Started != null)
            {
                Started(this, new LivePreviewStartedEventArgs());
            }

            var settings = new AsyncEffectRenderer.Settings()
            {
                ThreadCount    = PintaCore.System.RenderThreads,
                TileWidth      = render_bounds.Width,
                TileHeight     = 1,
                ThreadPriority = ThreadPriority.BelowNormal
            };

            Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss:ffff") + "Start Live preview.");

            renderer = new Renderer(this, settings);
            renderer.Start(effect, layer.Surface, live_preview_surface, render_bounds);

            if (effect.IsConfigurable)
            {
                if (!effect.LaunchConfiguration())
                {
                    PintaCore.Chrome.MainWindowBusy = true;
                    Cancel();
                }
                else
                {
                    PintaCore.Chrome.MainWindowBusy = true;
                    Apply();
                }
            }
            else
            {
                PintaCore.Chrome.MainWindowBusy = true;
                Apply();
            }
        }